OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 5989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6000 | 6000 |
6001 const int kToOffset = 0 * kPointerSize; | 6001 const int kToOffset = 0 * kPointerSize; |
6002 const int kFromOffset = 1 * kPointerSize; | 6002 const int kFromOffset = 1 * kPointerSize; |
6003 const int kStringOffset = 2 * kPointerSize; | 6003 const int kStringOffset = 2 * kPointerSize; |
6004 | 6004 |
6005 __ Ldrd(r2, r3, MemOperand(sp, kToOffset)); | 6005 __ Ldrd(r2, r3, MemOperand(sp, kToOffset)); |
6006 STATIC_ASSERT(kFromOffset == kToOffset + 4); | 6006 STATIC_ASSERT(kFromOffset == kToOffset + 4); |
6007 STATIC_ASSERT(kSmiTag == 0); | 6007 STATIC_ASSERT(kSmiTag == 0); |
6008 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); | 6008 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); |
6009 | 6009 |
6010 // I.e., arithmetic shift right by one un-smi-tags. | 6010 // Arithmetic shift right by one un-smi-tags. In this case we rotate right |
6011 __ mov(r2, Operand(r2, ASR, 1), SetCC); | 6011 // instead because we bail out on non-smi values: ROR and ASR are equivalent |
6012 __ mov(r3, Operand(r3, ASR, 1), SetCC, cc); | 6012 // for smis but they set the flags in a way that's easier to optimize. |
6013 // If either to or from had the smi tag bit set, then carry is set now. | 6013 __ mov(r2, Operand(r2, ROR, 1), SetCC); |
6014 __ b(cs, &runtime); // Either "from" or "to" is not a smi. | 6014 __ mov(r3, Operand(r3, ROR, 1), SetCC, cc); |
| 6015 // If either to or from had the smi tag bit set, then C is set now, and N |
| 6016 // has the same value: we rotated by 1, so the bottom bit is now the top bit. |
6015 // We want to bailout to runtime here if From is negative. In that case, the | 6017 // We want to bailout to runtime here if From is negative. In that case, the |
6016 // next instruction is not executed and we fall through to bailing out to | 6018 // next instruction is not executed and we fall through to bailing out to |
6017 // runtime. pl is the opposite of mi. | 6019 // runtime. |
6018 // Both r2 and r3 are untagged integers. | 6020 // Executed if both r2 and r3 are untagged integers. |
6019 __ sub(r2, r2, Operand(r3), SetCC, pl); | 6021 __ sub(r2, r2, Operand(r3), SetCC, cc); |
6020 __ b(mi, &runtime); // Fail if from > to. | 6022 // One of the above un-smis or the above SUB could have set N==1. |
| 6023 __ b(mi, &runtime); // Either "from" or "to" is not an smi, or from > to. |
6021 | 6024 |
6022 // Make sure first argument is a string. | 6025 // Make sure first argument is a string. |
6023 __ ldr(r0, MemOperand(sp, kStringOffset)); | 6026 __ ldr(r0, MemOperand(sp, kStringOffset)); |
6024 STATIC_ASSERT(kSmiTag == 0); | 6027 STATIC_ASSERT(kSmiTag == 0); |
6025 __ JumpIfSmi(r0, &runtime); | 6028 // Do a JumpIfSmi, but fold its jump into the subsequent string test. |
6026 Condition is_string = masm->IsObjectStringType(r0, r1); | 6029 __ tst(r0, Operand(kSmiTagMask)); |
| 6030 Condition is_string = masm->IsObjectStringType(r0, r1, ne); |
| 6031 ASSERT(is_string == eq); |
6027 __ b(NegateCondition(is_string), &runtime); | 6032 __ b(NegateCondition(is_string), &runtime); |
6028 | 6033 |
6029 // Short-cut for the case of trivial substring. | 6034 // Short-cut for the case of trivial substring. |
6030 Label return_r0; | 6035 Label return_r0; |
6031 // r0: original string | 6036 // r0: original string |
6032 // r2: result string length | 6037 // r2: result string length |
6033 __ ldr(r4, FieldMemOperand(r0, String::kLengthOffset)); | 6038 __ ldr(r4, FieldMemOperand(r0, String::kLengthOffset)); |
6034 __ cmp(r2, Operand(r4, ASR, 1)); | 6039 __ cmp(r2, Operand(r4, ASR, 1)); |
6035 // Return original string. | 6040 // Return original string. |
6036 __ b(eq, &return_r0); | 6041 __ b(eq, &return_r0); |
(...skipping 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7632 | 7637 |
7633 __ Pop(lr, r5, r1); | 7638 __ Pop(lr, r5, r1); |
7634 __ Ret(); | 7639 __ Ret(); |
7635 } | 7640 } |
7636 | 7641 |
7637 #undef __ | 7642 #undef __ |
7638 | 7643 |
7639 } } // namespace v8::internal | 7644 } } // namespace v8::internal |
7640 | 7645 |
7641 #endif // V8_TARGET_ARCH_ARM | 7646 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |