| 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 |