OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_PPC_MACRO_ASSEMBLER_PPC_H_ | 5 #ifndef V8_PPC_MACRO_ASSEMBLER_PPC_H_ |
6 #define V8_PPC_MACRO_ASSEMBLER_PPC_H_ | 6 #define V8_PPC_MACRO_ASSEMBLER_PPC_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/frames.h" | 10 #include "src/frames.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 // at the address pointed to by the addr register. Only works if addr is not | 170 // at the address pointed to by the addr register. Only works if addr is not |
171 // in new space. | 171 // in new space. |
172 void RememberedSetHelper(Register object, // Used for debug code. | 172 void RememberedSetHelper(Register object, // Used for debug code. |
173 Register addr, Register scratch, | 173 Register addr, Register scratch, |
174 SaveFPRegsMode save_fp, | 174 SaveFPRegsMode save_fp, |
175 RememberedSetFinalAction and_then); | 175 RememberedSetFinalAction and_then); |
176 | 176 |
177 void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, | 177 void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, |
178 Label* condition_met); | 178 Label* condition_met); |
179 | 179 |
180 void CheckMapDeprecated(Handle<Map> map, Register scratch, | |
181 Label* if_deprecated); | |
182 | |
183 // Check if object is in new space. Jumps if the object is not in new space. | 180 // Check if object is in new space. Jumps if the object is not in new space. |
184 // The register scratch can be object itself, but scratch will be clobbered. | 181 // The register scratch can be object itself, but scratch will be clobbered. |
185 void JumpIfNotInNewSpace(Register object, Register scratch, Label* branch) { | 182 void JumpIfNotInNewSpace(Register object, Register scratch, Label* branch) { |
186 InNewSpace(object, scratch, ne, branch); | 183 InNewSpace(object, scratch, ne, branch); |
187 } | 184 } |
188 | 185 |
189 // Check if object is in new space. Jumps if the object is in new space. | 186 // Check if object is in new space. Jumps if the object is in new space. |
190 // The register scratch can be object itself, but it will be clobbered. | 187 // The register scratch can be object itself, but it will be clobbered. |
191 void JumpIfInNewSpace(Register object, Register scratch, Label* branch) { | 188 void JumpIfInNewSpace(Register object, Register scratch, Label* branch) { |
192 InNewSpace(object, scratch, eq, branch); | 189 InNewSpace(object, scratch, eq, branch); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 void Prologue(bool code_pre_aging, int prologue_offset = 0); | 379 void Prologue(bool code_pre_aging, int prologue_offset = 0); |
383 | 380 |
384 // Enter exit frame. | 381 // Enter exit frame. |
385 // stack_space - extra stack space, used for alignment before call to C. | 382 // stack_space - extra stack space, used for alignment before call to C. |
386 void EnterExitFrame(bool save_doubles, int stack_space = 0); | 383 void EnterExitFrame(bool save_doubles, int stack_space = 0); |
387 | 384 |
388 // Leave the current exit frame. Expects the return value in r0. | 385 // Leave the current exit frame. Expects the return value in r0. |
389 // Expect the number of values, pushed prior to the exit frame, to | 386 // Expect the number of values, pushed prior to the exit frame, to |
390 // remove in a register (or no_reg, if there is nothing to remove). | 387 // remove in a register (or no_reg, if there is nothing to remove). |
391 void LeaveExitFrame(bool save_doubles, Register argument_count, | 388 void LeaveExitFrame(bool save_doubles, Register argument_count, |
392 bool restore_context); | 389 bool restore_context, |
| 390 bool argument_count_is_length = false); |
393 | 391 |
394 // Get the actual activation frame alignment for target environment. | 392 // Get the actual activation frame alignment for target environment. |
395 static int ActivationFrameAlignment(); | 393 static int ActivationFrameAlignment(); |
396 | 394 |
397 void LoadContext(Register dst, int context_chain_length); | 395 void LoadContext(Register dst, int context_chain_length); |
398 | 396 |
399 // Conditionally load the cached Array transitioned map of type | 397 // Conditionally load the cached Array transitioned map of type |
400 // transitioned_kind from the native context if the map in register | 398 // transitioned_kind from the native context if the map in register |
401 // map_in_out is the cached Array map in the native context of | 399 // map_in_out is the cached Array map in the native context of |
402 // expected_kind. | 400 // expected_kind. |
(...skipping 23 matching lines...) Expand all Loading... |
426 // load a literal signed int value <value> to GPR <dst> | 424 // load a literal signed int value <value> to GPR <dst> |
427 void LoadIntLiteral(Register dst, int value); | 425 void LoadIntLiteral(Register dst, int value); |
428 | 426 |
429 // load an SMI value <value> to GPR <dst> | 427 // load an SMI value <value> to GPR <dst> |
430 void LoadSmiLiteral(Register dst, Smi* smi); | 428 void LoadSmiLiteral(Register dst, Smi* smi); |
431 | 429 |
432 // load a literal double value <value> to FPR <result> | 430 // load a literal double value <value> to FPR <result> |
433 void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch); | 431 void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch); |
434 | 432 |
435 void LoadWord(Register dst, const MemOperand& mem, Register scratch); | 433 void LoadWord(Register dst, const MemOperand& mem, Register scratch); |
436 | |
437 void LoadWordArith(Register dst, const MemOperand& mem, | 434 void LoadWordArith(Register dst, const MemOperand& mem, |
438 Register scratch = no_reg); | 435 Register scratch = no_reg); |
439 | |
440 void StoreWord(Register src, const MemOperand& mem, Register scratch); | 436 void StoreWord(Register src, const MemOperand& mem, Register scratch); |
441 | 437 |
442 void LoadHalfWord(Register dst, const MemOperand& mem, Register scratch); | 438 void LoadHalfWord(Register dst, const MemOperand& mem, Register scratch); |
443 | 439 void LoadHalfWordArith(Register dst, const MemOperand& mem, |
| 440 Register scratch = no_reg); |
444 void StoreHalfWord(Register src, const MemOperand& mem, Register scratch); | 441 void StoreHalfWord(Register src, const MemOperand& mem, Register scratch); |
445 | 442 |
446 void LoadByte(Register dst, const MemOperand& mem, Register scratch); | 443 void LoadByte(Register dst, const MemOperand& mem, Register scratch); |
447 | |
448 void StoreByte(Register src, const MemOperand& mem, Register scratch); | 444 void StoreByte(Register src, const MemOperand& mem, Register scratch); |
449 | 445 |
450 void LoadRepresentation(Register dst, const MemOperand& mem, Representation r, | 446 void LoadRepresentation(Register dst, const MemOperand& mem, Representation r, |
451 Register scratch = no_reg); | 447 Register scratch = no_reg); |
452 | |
453 void StoreRepresentation(Register src, const MemOperand& mem, | 448 void StoreRepresentation(Register src, const MemOperand& mem, |
454 Representation r, Register scratch = no_reg); | 449 Representation r, Register scratch = no_reg); |
455 | 450 |
| 451 void LoadDouble(DoubleRegister dst, const MemOperand& mem, Register scratch); |
| 452 void StoreDouble(DoubleRegister src, const MemOperand& mem, Register scratch); |
| 453 |
456 // Move values between integer and floating point registers. | 454 // Move values between integer and floating point registers. |
457 void MovIntToDouble(DoubleRegister dst, Register src, Register scratch); | 455 void MovIntToDouble(DoubleRegister dst, Register src, Register scratch); |
458 void MovUnsignedIntToDouble(DoubleRegister dst, Register src, | 456 void MovUnsignedIntToDouble(DoubleRegister dst, Register src, |
459 Register scratch); | 457 Register scratch); |
460 void MovInt64ToDouble(DoubleRegister dst, | 458 void MovInt64ToDouble(DoubleRegister dst, |
461 #if !V8_TARGET_ARCH_PPC64 | 459 #if !V8_TARGET_ARCH_PPC64 |
462 Register src_hi, | 460 Register src_hi, |
463 #endif | 461 #endif |
464 Register src); | 462 Register src); |
465 #if V8_TARGET_ARCH_PPC64 | 463 #if V8_TARGET_ARCH_PPC64 |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match | 753 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match |
756 // against maps that are ElementsKind transition maps of the specified map. | 754 // against maps that are ElementsKind transition maps of the specified map. |
757 void CheckMap(Register obj, Register scratch, Handle<Map> map, Label* fail, | 755 void CheckMap(Register obj, Register scratch, Handle<Map> map, Label* fail, |
758 SmiCheckType smi_check_type); | 756 SmiCheckType smi_check_type); |
759 | 757 |
760 | 758 |
761 void CheckMap(Register obj, Register scratch, Heap::RootListIndex index, | 759 void CheckMap(Register obj, Register scratch, Heap::RootListIndex index, |
762 Label* fail, SmiCheckType smi_check_type); | 760 Label* fail, SmiCheckType smi_check_type); |
763 | 761 |
764 | 762 |
765 // Check if the map of an object is equal to a specified map and branch to a | 763 // Check if the map of an object is equal to a specified weak map and branch |
766 // specified target if equal. Skip the smi check if not required (object is | 764 // to a specified target if equal. Skip the smi check if not required |
767 // known to be a heap object) | 765 // (object is known to be a heap object) |
768 void DispatchMap(Register obj, Register scratch, Handle<Map> map, | 766 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, |
769 Handle<Code> success, SmiCheckType smi_check_type); | 767 Handle<WeakCell> cell, Handle<Code> success, |
| 768 SmiCheckType smi_check_type); |
770 | 769 |
| 770 // Compare the given value and the value of weak cell. |
| 771 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch, |
| 772 CRegister cr = cr7); |
| 773 |
| 774 void GetWeakValue(Register value, Handle<WeakCell> cell); |
| 775 |
| 776 // Load the value of the weak cell in the value register. Branch to the given |
| 777 // miss label if the weak cell was cleared. |
| 778 void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss); |
771 | 779 |
772 // Compare the object in a register to a value from the root list. | 780 // Compare the object in a register to a value from the root list. |
773 // Uses the ip register as scratch. | 781 // Uses the ip register as scratch. |
774 void CompareRoot(Register obj, Heap::RootListIndex index); | 782 void CompareRoot(Register obj, Heap::RootListIndex index); |
775 | 783 |
776 | 784 |
777 // Load and check the instance type of an object for being a string. | 785 // Load and check the instance type of an object for being a string. |
778 // Loads the type into the second argument register. | 786 // Loads the type into the second argument register. |
779 // Returns a condition that will be enabled if the object was a string. | 787 // Returns a condition that will be enabled if the object was a string. |
780 Condition IsObjectStringType(Register obj, Register type) { | 788 Condition IsObjectStringType(Register obj, Register type) { |
781 LoadP(type, FieldMemOperand(obj, HeapObject::kMapOffset)); | 789 LoadP(type, FieldMemOperand(obj, HeapObject::kMapOffset)); |
782 lbz(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); | 790 lbz(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); |
783 andi(r0, type, Operand(kIsNotStringMask)); | 791 andi(r0, type, Operand(kIsNotStringMask)); |
784 DCHECK_EQ(0, kStringTag); | 792 DCHECK_EQ(0u, kStringTag); |
785 return eq; | 793 return eq; |
786 } | 794 } |
787 | 795 |
788 | 796 |
789 // Picks out an array index from the hash field. | 797 // Picks out an array index from the hash field. |
790 // Register use: | 798 // Register use: |
791 // hash - holds the index's hash. Clobbered. | 799 // hash - holds the index's hash. Clobbered. |
792 // index - holds the overwritten index on exit. | 800 // index - holds the overwritten index on exit. |
793 void IndexFromHash(Register hash, Register index); | 801 void IndexFromHash(Register hash, Register index); |
794 | 802 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 void CallCFunction(ExternalReference function, int num_arguments); | 966 void CallCFunction(ExternalReference function, int num_arguments); |
959 void CallCFunction(Register function, int num_arguments); | 967 void CallCFunction(Register function, int num_arguments); |
960 void CallCFunction(ExternalReference function, int num_reg_arguments, | 968 void CallCFunction(ExternalReference function, int num_reg_arguments, |
961 int num_double_arguments); | 969 int num_double_arguments); |
962 void CallCFunction(Register function, int num_reg_arguments, | 970 void CallCFunction(Register function, int num_reg_arguments, |
963 int num_double_arguments); | 971 int num_double_arguments); |
964 | 972 |
965 void MovFromFloatParameter(DoubleRegister dst); | 973 void MovFromFloatParameter(DoubleRegister dst); |
966 void MovFromFloatResult(DoubleRegister dst); | 974 void MovFromFloatResult(DoubleRegister dst); |
967 | 975 |
968 // Calls an API function. Allocates HandleScope, extracts returned value | |
969 // from handle and propagates exceptions. Restores context. stack_space | |
970 // - space to be unwound on exit (includes the call JS arguments space and | |
971 // the additional space allocated for the fast call). | |
972 void CallApiFunctionAndReturn(Register function_address, | |
973 ExternalReference thunk_ref, int stack_space, | |
974 MemOperand return_value_operand, | |
975 MemOperand* context_restore_operand); | |
976 | |
977 // Jump to a runtime routine. | 976 // Jump to a runtime routine. |
978 void JumpToExternalReference(const ExternalReference& builtin); | 977 void JumpToExternalReference(const ExternalReference& builtin); |
979 | 978 |
980 // Invoke specified builtin JavaScript function. Adds an entry to | 979 // Invoke specified builtin JavaScript function. Adds an entry to |
981 // the unresolved list if the name does not resolve. | 980 // the unresolved list if the name does not resolve. |
982 void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, | 981 void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, |
983 const CallWrapper& call_wrapper = NullCallWrapper()); | 982 const CallWrapper& call_wrapper = NullCallWrapper()); |
984 | 983 |
985 // Store the code object for the given builtin in the target register and | 984 // Store the code object for the given builtin in the target register and |
986 // setup the function in r1. | 985 // setup the function in r1. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 // Test consecutive bit range in value. Range is defined by mask. | 1115 // Test consecutive bit range in value. Range is defined by mask. |
1117 inline void TestBitMask(Register value, uintptr_t mask, | 1116 inline void TestBitMask(Register value, uintptr_t mask, |
1118 Register scratch = r0) { | 1117 Register scratch = r0) { |
1119 ExtractBitMask(scratch, value, mask, SetRC); | 1118 ExtractBitMask(scratch, value, mask, SetRC); |
1120 } | 1119 } |
1121 | 1120 |
1122 | 1121 |
1123 // --------------------------------------------------------------------------- | 1122 // --------------------------------------------------------------------------- |
1124 // Smi utilities | 1123 // Smi utilities |
1125 | 1124 |
1126 // Shift left by 1 | 1125 // Shift left by kSmiShift |
1127 void SmiTag(Register reg, RCBit rc = LeaveRC) { SmiTag(reg, reg, rc); } | 1126 void SmiTag(Register reg, RCBit rc = LeaveRC) { SmiTag(reg, reg, rc); } |
1128 void SmiTag(Register dst, Register src, RCBit rc = LeaveRC) { | 1127 void SmiTag(Register dst, Register src, RCBit rc = LeaveRC) { |
1129 ShiftLeftImm(dst, src, Operand(kSmiShift), rc); | 1128 ShiftLeftImm(dst, src, Operand(kSmiShift), rc); |
1130 } | 1129 } |
1131 | 1130 |
1132 #if !V8_TARGET_ARCH_PPC64 | 1131 #if !V8_TARGET_ARCH_PPC64 |
1133 // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow(). | 1132 // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow(). |
1134 void SmiTagCheckOverflow(Register reg, Register overflow); | 1133 void SmiTagCheckOverflow(Register reg, Register overflow); |
1135 void SmiTagCheckOverflow(Register dst, Register src, Register overflow); | 1134 void SmiTagCheckOverflow(Register dst, Register src, Register overflow); |
1136 | 1135 |
1137 inline void JumpIfNotSmiCandidate(Register value, Register scratch, | 1136 inline void JumpIfNotSmiCandidate(Register value, Register scratch, |
1138 Label* not_smi_label) { | 1137 Label* not_smi_label) { |
1139 // High bits must be identical to fit into an Smi | 1138 // High bits must be identical to fit into an Smi |
| 1139 STATIC_ASSERT(kSmiShift == 1); |
1140 addis(scratch, value, Operand(0x40000000u >> 16)); | 1140 addis(scratch, value, Operand(0x40000000u >> 16)); |
1141 cmpi(scratch, Operand::Zero()); | 1141 cmpi(scratch, Operand::Zero()); |
1142 blt(not_smi_label); | 1142 blt(not_smi_label); |
1143 } | 1143 } |
1144 #endif | 1144 #endif |
1145 inline void TestUnsignedSmiCandidate(Register value, Register scratch) { | 1145 inline void TestUnsignedSmiCandidate(Register value, Register scratch) { |
1146 // The test is different for unsigned int values. Since we need | 1146 // The test is different for unsigned int values. Since we need |
1147 // the value to be in the range of a positive smi, we can't | 1147 // the value to be in the range of a positive smi, we can't |
1148 // handle any of the high bits being set in the value. | 1148 // handle any of the high bits being set in the value. |
1149 TestBitRange(value, kBitsPerPointer - 1, kBitsPerPointer - 1 - kSmiShift, | 1149 TestBitRange(value, kBitsPerPointer - 1, kBitsPerPointer - 1 - kSmiShift, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 | 1228 |
1229 // Untag the source value into destination and jump if source is a smi. | 1229 // Untag the source value into destination and jump if source is a smi. |
1230 // Souce and destination can be the same register. | 1230 // Souce and destination can be the same register. |
1231 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case); | 1231 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case); |
1232 | 1232 |
1233 // Untag the source value into destination and jump if source is not a smi. | 1233 // Untag the source value into destination and jump if source is not a smi. |
1234 // Souce and destination can be the same register. | 1234 // Souce and destination can be the same register. |
1235 void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); | 1235 void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); |
1236 | 1236 |
1237 inline void TestIfSmi(Register value, Register scratch) { | 1237 inline void TestIfSmi(Register value, Register scratch) { |
1238 TestBit(value, 0, scratch); // tst(value, Operand(kSmiTagMask)); | 1238 TestBitRange(value, kSmiTagSize - 1, 0, scratch); |
1239 } | 1239 } |
1240 | 1240 |
1241 inline void TestIfPositiveSmi(Register value, Register scratch) { | 1241 inline void TestIfPositiveSmi(Register value, Register scratch) { |
1242 STATIC_ASSERT((kSmiTagMask | kSmiSignMask) == | |
1243 (intptr_t)(1UL << (kBitsPerPointer - 1) | 1)); | |
1244 #if V8_TARGET_ARCH_PPC64 | 1242 #if V8_TARGET_ARCH_PPC64 |
1245 rldicl(scratch, value, 1, kBitsPerPointer - 2, SetRC); | 1243 rldicl(scratch, value, 1, kBitsPerPointer - (1 + kSmiTagSize), SetRC); |
1246 #else | 1244 #else |
1247 rlwinm(scratch, value, 1, kBitsPerPointer - 2, kBitsPerPointer - 1, SetRC); | 1245 rlwinm(scratch, value, 1, kBitsPerPointer - (1 + kSmiTagSize), |
| 1246 kBitsPerPointer - 1, SetRC); |
1248 #endif | 1247 #endif |
1249 } | 1248 } |
1250 | 1249 |
1251 // Jump the register contains a smi. | 1250 // Jump the register contains a smi. |
1252 inline void JumpIfSmi(Register value, Label* smi_label) { | 1251 inline void JumpIfSmi(Register value, Label* smi_label) { |
1253 TestIfSmi(value, r0); | 1252 TestIfSmi(value, r0); |
1254 beq(smi_label, cr0); // branch if SMI | 1253 beq(smi_label, cr0); // branch if SMI |
1255 } | 1254 } |
1256 // Jump if either of the registers contain a non-smi. | 1255 // Jump if either of the registers contain a non-smi. |
1257 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { | 1256 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { |
1258 TestIfSmi(value, r0); | 1257 TestIfSmi(value, r0); |
1259 bne(not_smi_label, cr0); | 1258 bne(not_smi_label, cr0); |
1260 } | 1259 } |
1261 // Jump if either of the registers contain a non-smi. | 1260 // Jump if either of the registers contain a non-smi. |
1262 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); | 1261 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); |
1263 // Jump if either of the registers contain a smi. | 1262 // Jump if either of the registers contain a smi. |
1264 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); | 1263 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); |
1265 | 1264 |
1266 // Abort execution if argument is a smi, enabled via --debug-code. | 1265 // Abort execution if argument is a smi, enabled via --debug-code. |
1267 void AssertNotSmi(Register object); | 1266 void AssertNotSmi(Register object); |
1268 void AssertSmi(Register object); | 1267 void AssertSmi(Register object); |
1269 | 1268 |
1270 | 1269 |
1271 #if V8_TARGET_ARCH_PPC64 | 1270 #if V8_TARGET_ARCH_PPC64 |
1272 inline void TestIfInt32(Register value, Register scratch1, Register scratch2, | 1271 inline void TestIfInt32(Register value, Register scratch, |
1273 CRegister cr = cr7) { | 1272 CRegister cr = cr7) { |
1274 // High bits must be identical to fit into an 32-bit integer | 1273 // High bits must be identical to fit into an 32-bit integer |
1275 srawi(scratch1, value, 31); | 1274 extsw(scratch, value); |
1276 sradi(scratch2, value, 32); | 1275 cmp(scratch, value, cr); |
1277 cmp(scratch1, scratch2, cr); | |
1278 } | 1276 } |
1279 #else | 1277 #else |
1280 inline void TestIfInt32(Register hi_word, Register lo_word, Register scratch, | 1278 inline void TestIfInt32(Register hi_word, Register lo_word, Register scratch, |
1281 CRegister cr = cr7) { | 1279 CRegister cr = cr7) { |
1282 // High bits must be identical to fit into an 32-bit integer | 1280 // High bits must be identical to fit into an 32-bit integer |
1283 srawi(scratch, lo_word, 31); | 1281 srawi(scratch, lo_word, 31); |
1284 cmp(scratch, hi_word, cr); | 1282 cmp(scratch, hi_word, cr); |
1285 } | 1283 } |
1286 #endif | 1284 #endif |
1287 | 1285 |
| 1286 #if V8_TARGET_ARCH_PPC64 |
| 1287 // Ensure it is permissable to read/write int value directly from |
| 1288 // upper half of the smi. |
| 1289 STATIC_ASSERT(kSmiTag == 0); |
| 1290 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
| 1291 #endif |
| 1292 #if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN |
| 1293 #define SmiWordOffset(offset) (offset + kPointerSize / 2) |
| 1294 #else |
| 1295 #define SmiWordOffset(offset) offset |
| 1296 #endif |
| 1297 |
1288 // Abort execution if argument is not a string, enabled via --debug-code. | 1298 // Abort execution if argument is not a string, enabled via --debug-code. |
1289 void AssertString(Register object); | 1299 void AssertString(Register object); |
1290 | 1300 |
1291 // Abort execution if argument is not a name, enabled via --debug-code. | 1301 // Abort execution if argument is not a name, enabled via --debug-code. |
1292 void AssertName(Register object); | 1302 void AssertName(Register object); |
1293 | 1303 |
1294 // Abort execution if argument is not undefined or an AllocationSite, enabled | 1304 // Abort execution if argument is not undefined or an AllocationSite, enabled |
1295 // via --debug-code. | 1305 // via --debug-code. |
1296 void AssertUndefinedOrAllocationSite(Register object, Register scratch); | 1306 void AssertUndefinedOrAllocationSite(Register object, Register scratch); |
1297 | 1307 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 // if input_value < 0, output_value is 0 | 1372 // if input_value < 0, output_value is 0 |
1363 // if input_value > 255, output_value is 255 | 1373 // if input_value > 255, output_value is 255 |
1364 // otherwise output_value is the (int)input_value (round to nearest) | 1374 // otherwise output_value is the (int)input_value (round to nearest) |
1365 void ClampDoubleToUint8(Register result_reg, DoubleRegister input_reg, | 1375 void ClampDoubleToUint8(Register result_reg, DoubleRegister input_reg, |
1366 DoubleRegister temp_double_reg); | 1376 DoubleRegister temp_double_reg); |
1367 | 1377 |
1368 | 1378 |
1369 void LoadInstanceDescriptors(Register map, Register descriptors); | 1379 void LoadInstanceDescriptors(Register map, Register descriptors); |
1370 void EnumLength(Register dst, Register map); | 1380 void EnumLength(Register dst, Register map); |
1371 void NumberOfOwnDescriptors(Register dst, Register map); | 1381 void NumberOfOwnDescriptors(Register dst, Register map); |
| 1382 void LoadAccessor(Register dst, Register holder, int accessor_index, |
| 1383 AccessorComponent accessor); |
1372 | 1384 |
1373 template <typename Field> | 1385 template <typename Field> |
1374 void DecodeField(Register dst, Register src) { | 1386 void DecodeField(Register dst, Register src, RCBit rc = LeaveRC) { |
1375 ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift); | 1387 ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift, |
| 1388 rc); |
1376 } | 1389 } |
1377 | 1390 |
1378 template <typename Field> | 1391 template <typename Field> |
1379 void DecodeField(Register reg) { | 1392 void DecodeField(Register reg, RCBit rc = LeaveRC) { |
1380 DecodeField<Field>(reg, reg); | 1393 DecodeField<Field>(reg, reg, rc); |
1381 } | 1394 } |
1382 | 1395 |
1383 template <typename Field> | 1396 template <typename Field> |
1384 void DecodeFieldToSmi(Register dst, Register src) { | 1397 void DecodeFieldToSmi(Register dst, Register src) { |
1385 #if V8_TARGET_ARCH_PPC64 | 1398 #if V8_TARGET_ARCH_PPC64 |
1386 DecodeField<Field>(dst, src); | 1399 DecodeField<Field>(dst, src); |
1387 SmiTag(dst); | 1400 SmiTag(dst); |
1388 #else | 1401 #else |
1389 // 32-bit can do this in one instruction: | 1402 // 32-bit can do this in one instruction: |
1390 int start = Field::kSize + kSmiShift - 1; | 1403 int start = Field::kSize + kSmiShift - 1; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 #define ACCESS_MASM(masm) \ | 1558 #define ACCESS_MASM(masm) \ |
1546 masm->stop(__FILE_LINE__); \ | 1559 masm->stop(__FILE_LINE__); \ |
1547 masm-> | 1560 masm-> |
1548 #else | 1561 #else |
1549 #define ACCESS_MASM(masm) masm-> | 1562 #define ACCESS_MASM(masm) masm-> |
1550 #endif | 1563 #endif |
1551 } | 1564 } |
1552 } // namespace v8::internal | 1565 } // namespace v8::internal |
1553 | 1566 |
1554 #endif // V8_PPC_MACRO_ASSEMBLER_PPC_H_ | 1567 #endif // V8_PPC_MACRO_ASSEMBLER_PPC_H_ |
OLD | NEW |