Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2465)

Side by Side Diff: src/s390/macro-assembler-s390.h

Issue 1725243004: S390: Initial impl of S390 asm, masm, code-stubs,... (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Updated BUILD.gn + cpu-s390.cc to addr @jochen's comments. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_S390_MACRO_ASSEMBLER_S390_H_
6 #define V8_PPC_MACRO_ASSEMBLER_PPC_H_ 6 #define V8_S390_MACRO_ASSEMBLER_S390_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"
11 #include "src/globals.h" 11 #include "src/globals.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 // Give alias names to registers for calling conventions. 16 // Give alias names to registers for calling conventions.
17 const Register kReturnRegister0 = {Register::kCode_r3}; 17 const Register kReturnRegister0 = {Register::kCode_r2};
18 const Register kReturnRegister1 = {Register::kCode_r4}; 18 const Register kReturnRegister1 = {Register::kCode_r3};
19 const Register kReturnRegister2 = {Register::kCode_r5}; 19 const Register kReturnRegister2 = {Register::kCode_r4};
20 const Register kJSFunctionRegister = {Register::kCode_r4}; 20 const Register kJSFunctionRegister = {Register::kCode_r3};
21 const Register kContextRegister = {Register::kCode_r30}; 21 const Register kContextRegister = {Register::kCode_r13};
22 const Register kInterpreterAccumulatorRegister = {Register::kCode_r3}; 22 const Register kInterpreterAccumulatorRegister = {Register::kCode_r2};
23 const Register kInterpreterRegisterFileRegister = {Register::kCode_r14}; 23 const Register kInterpreterRegisterFileRegister = {Register::kCode_r4};
24 const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r15}; 24 const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_r5};
25 const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r16}; 25 const Register kInterpreterBytecodeArrayRegister = {Register::kCode_r6};
26 const Register kInterpreterDispatchTableRegister = {Register::kCode_r17}; 26 const Register kInterpreterDispatchTableRegister = {Register::kCode_r8};
27 const Register kJavaScriptCallArgCountRegister = {Register::kCode_r3}; 27 const Register kJavaScriptCallArgCountRegister = {Register::kCode_r2};
28 const Register kJavaScriptCallNewTargetRegister = {Register::kCode_r6}; 28 const Register kJavaScriptCallNewTargetRegister = {Register::kCode_r5};
29 const Register kRuntimeCallFunctionRegister = {Register::kCode_r4}; 29 const Register kRuntimeCallFunctionRegister = {Register::kCode_r3};
30 const Register kRuntimeCallArgCountRegister = {Register::kCode_r3}; 30 const Register kRuntimeCallArgCountRegister = {Register::kCode_r2};
31 31
32 // ---------------------------------------------------------------------------- 32 // ----------------------------------------------------------------------------
33 // Static helper functions 33 // Static helper functions
34 34
35 // Generate a MemOperand for loading a field from an object. 35 // Generate a MemOperand for loading a field from an object.
36 inline MemOperand FieldMemOperand(Register object, int offset) { 36 inline MemOperand FieldMemOperand(Register object, int offset) {
37 return MemOperand(object, offset - kHeapObjectTag); 37 return MemOperand(object, offset - kHeapObjectTag);
38 } 38 }
39 39
40 // Generate a MemOperand for loading a field from an object.
41 inline MemOperand FieldMemOperand(Register object, Register index, int offset) {
42 return MemOperand(object, index, offset - kHeapObjectTag);
43 }
44
45 // Generate a MemOperand for loading a field from Root register
46 inline MemOperand RootMemOperand(Heap::RootListIndex index) {
47 return MemOperand(kRootRegister, index << kPointerSizeLog2);
48 }
40 49
41 // Flags used for AllocateHeapNumber 50 // Flags used for AllocateHeapNumber
42 enum TaggingMode { 51 enum TaggingMode {
43 // Tag the result. 52 // Tag the result.
44 TAG_RESULT, 53 TAG_RESULT,
45 // Don't tag 54 // Don't tag
46 DONT_TAG_RESULT 55 DONT_TAG_RESULT
47 }; 56 };
48 57
49
50 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; 58 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
51 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; 59 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
52 enum PointersToHereCheck { 60 enum PointersToHereCheck {
53 kPointersToHereMaybeInteresting, 61 kPointersToHereMaybeInteresting,
54 kPointersToHereAreAlwaysInteresting 62 kPointersToHereAreAlwaysInteresting
55 }; 63 };
56 enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved }; 64 enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
57 65
58
59 Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg, 66 Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
60 Register reg3 = no_reg, 67 Register reg3 = no_reg,
61 Register reg4 = no_reg, 68 Register reg4 = no_reg,
62 Register reg5 = no_reg, 69 Register reg5 = no_reg,
63 Register reg6 = no_reg); 70 Register reg6 = no_reg);
64 71
65
66 #ifdef DEBUG 72 #ifdef DEBUG
67 bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg, 73 bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
68 Register reg4 = no_reg, Register reg5 = no_reg, 74 Register reg4 = no_reg, Register reg5 = no_reg,
69 Register reg6 = no_reg, Register reg7 = no_reg, 75 Register reg6 = no_reg, Register reg7 = no_reg,
70 Register reg8 = no_reg, Register reg9 = no_reg, 76 Register reg8 = no_reg, Register reg9 = no_reg,
71 Register reg10 = no_reg); 77 Register reg10 = no_reg);
72 #endif 78 #endif
73 79
74 // These exist to provide portability between 32 and 64bit 80 // These exist to provide portability between 32 and 64bit
75 #if V8_TARGET_ARCH_PPC64 81 #if V8_TARGET_ARCH_S390X
76 #define LoadPU ldu
77 #define LoadPX ldx
78 #define LoadPUX ldux
79 #define StorePU stdu
80 #define StorePX stdx
81 #define StorePUX stdux
82 #define ShiftLeftImm sldi
83 #define ShiftRightImm srdi
84 #define ClearLeftImm clrldi
85 #define ClearRightImm clrrdi
86 #define ShiftRightArithImm sradi
87 #define ShiftLeft_ sld
88 #define ShiftRight_ srd
89 #define ShiftRightArith srad
90 #define Mul mulld
91 #define Div divd 82 #define Div divd
83
84 // The length of the arithmetic operation is the length
85 // of the register.
86
87 // Length:
88 // H = halfword
89 // W = word
90
91 // arithmetics and bitwise
92 #define AddMI agsi
93 #define AddRR agr
94 #define SubRR sgr
95 #define AndRR ngr
96 #define OrRR ogr
97 #define XorRR xgr
98 #define LoadComplementRR lcgr
99 #define LoadNegativeRR lngr
100
101 // Distinct Operands
102 #define AddP_RRR agrk
103 #define AddPImm_RRI aghik
104 #define AddLogicalP_RRR algrk
105 #define SubP_RRR sgrk
106 #define SubLogicalP_RRR slgrk
107 #define AndP_RRR ngrk
108 #define OrP_RRR ogrk
109 #define XorP_RRR xgrk
110
111 // Load / Store
112 #define LoadRR lgr
113 #define LoadAndTestRR ltgr
114 #define LoadImmP lghi
115 #define LoadLogicalHalfWordP llgh
116
117 // Compare
118 #define CmpPH cghi
119 #define CmpLogicalPW clgfi
120
121 // Shifts
122 #define ShiftLeftP sllg
123 #define ShiftRightP srlg
124 #define ShiftLeftArithP slag
125 #define ShiftRightArithP srag
92 #else 126 #else
93 #define LoadPU lwzu 127
94 #define LoadPX lwzx 128 // arithmetics and bitwise
95 #define LoadPUX lwzux 129 // Reg2Reg
96 #define StorePU stwu 130 #define AddMI asi
97 #define StorePX stwx 131 #define AddRR ar
98 #define StorePUX stwux 132 #define SubRR sr
99 #define ShiftLeftImm slwi 133 #define AndRR nr
100 #define ShiftRightImm srwi 134 #define OrRR or_z
101 #define ClearLeftImm clrlwi 135 #define XorRR xr
102 #define ClearRightImm clrrwi 136 #define LoadComplementRR lcr
103 #define ShiftRightArithImm srawi 137 #define LoadNegativeRR lnr
104 #define ShiftLeft_ slw 138
105 #define ShiftRight_ srw 139 // Distinct Operands
106 #define ShiftRightArith sraw 140 #define AddP_RRR ark
107 #define Mul mullw 141 #define AddPImm_RRI ahik
108 #define Div divw 142 #define AddLogicalP_RRR alrk
143 #define SubP_RRR srk
144 #define SubLogicalP_RRR slrk
145 #define AndP_RRR nrk
146 #define OrP_RRR ork
147 #define XorP_RRR xrk
148
149 // Load / Store
150 #define LoadRR lr
151 #define LoadAndTestRR ltr
152 #define LoadImmP lhi
153 #define LoadLogicalHalfWordP llh
154
155 // Compare
156 #define CmpPH chi
157 #define CmpLogicalPW clfi
158
159 // Shifts
160 #define ShiftLeftP ShiftLeft
161 #define ShiftRightP ShiftRight
162 #define ShiftLeftArithP ShiftLeftArith
163 #define ShiftRightArithP ShiftRightArith
164
109 #endif 165 #endif
110 166
111
112 // MacroAssembler implements a collection of frequently used macros. 167 // MacroAssembler implements a collection of frequently used macros.
113 class MacroAssembler : public Assembler { 168 class MacroAssembler : public Assembler {
114 public: 169 public:
115 MacroAssembler(Isolate* isolate, void* buffer, int size, 170 MacroAssembler(Isolate* isolate, void* buffer, int size,
116 CodeObjectRequired create_code_object); 171 CodeObjectRequired create_code_object);
117 172
118 173 // Returns the size of a call in instructions.
119 // Returns the size of a call in instructions. Note, the value returned is
120 // only valid as long as no entries are added to the constant pool between
121 // checking the call size and emitting the actual call.
122 static int CallSize(Register target); 174 static int CallSize(Register target);
123 int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al); 175 int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
124 static int CallSizeNotPredictableCodeSize(Address target, 176 static int CallSizeNotPredictableCodeSize(Address target,
125 RelocInfo::Mode rmode, 177 RelocInfo::Mode rmode,
126 Condition cond = al); 178 Condition cond = al);
127 179
128 // Jump, Call, and Ret pseudo instructions implementing inter-working. 180 // Jump, Call, and Ret pseudo instructions implementing inter-working.
129 void Jump(Register target); 181 void Jump(Register target);
130 void JumpToJSEntry(Register target); 182 void JumpToJSEntry(Register target);
131 void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al, 183 void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al,
132 CRegister cr = cr7); 184 CRegister cr = cr7);
133 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al); 185 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
134 void Call(Register target); 186 void Call(Register target);
135 void CallJSEntry(Register target); 187 void CallJSEntry(Register target);
136 void Call(Address target, RelocInfo::Mode rmode, Condition cond = al); 188 void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
137 int CallSize(Handle<Code> code, 189 int CallSize(Handle<Code> code,
138 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 190 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
139 TypeFeedbackId ast_id = TypeFeedbackId::None(), 191 TypeFeedbackId ast_id = TypeFeedbackId::None(),
140 Condition cond = al); 192 Condition cond = al);
141 void Call(Handle<Code> code, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET, 193 void Call(Handle<Code> code, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
142 TypeFeedbackId ast_id = TypeFeedbackId::None(), 194 TypeFeedbackId ast_id = TypeFeedbackId::None(),
143 Condition cond = al); 195 Condition cond = al);
144 void Ret() { blr(); } 196 void Ret() { b(r14); }
145 void Ret(Condition cond, CRegister cr = cr7) { bclr(cond, cr); } 197 void Ret(Condition cond) { b(cond, r14); }
146 198
147 // Emit code to discard a non-negative number of pointer-sized elements 199 // Emit code to discard a non-negative number of pointer-sized elements
148 // from the stack, clobbering only the sp register. 200 // from the stack, clobbering only the sp register.
149 void Drop(int count); 201 void Drop(int count);
150 void Drop(Register count, Register scratch = r0); 202 void Drop(Register count, Register scratch = r0);
151 203
152 void Ret(int drop) { 204 void Ret(int drop) {
153 Drop(drop); 205 Drop(drop);
154 blr(); 206 Ret();
155 } 207 }
156 208
157 void Call(Label* target); 209 void Call(Label* target);
158 210
159 // Emit call to the code we are currently generating. 211 // Emit call to the code we are currently generating.
160 void CallSelf() { 212 void CallSelf() {
161 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 213 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
162 Call(self, RelocInfo::CODE_TARGET); 214 Call(self, RelocInfo::CODE_TARGET);
163 } 215 }
164 216
165 // Register move. May do nothing if the registers are identical. 217 // Register move. May do nothing if the registers are identical.
166 void Move(Register dst, Smi* smi) { LoadSmiLiteral(dst, smi); } 218 void Move(Register dst, Smi* smi) { LoadSmiLiteral(dst, smi); }
167 void Move(Register dst, Handle<Object> value); 219 void Move(Register dst, Handle<Object> value);
168 void Move(Register dst, Register src, Condition cond = al); 220 void Move(Register dst, Register src, Condition cond = al);
169 void Move(DoubleRegister dst, DoubleRegister src); 221 void Move(DoubleRegister dst, DoubleRegister src);
170 222
223 void InsertDoubleLow(DoubleRegister dst, Register src);
224 void InsertDoubleHigh(DoubleRegister dst, Register src);
225
171 void MultiPush(RegList regs, Register location = sp); 226 void MultiPush(RegList regs, Register location = sp);
172 void MultiPop(RegList regs, Register location = sp); 227 void MultiPop(RegList regs, Register location = sp);
173 228
174 void MultiPushDoubles(RegList dregs, Register location = sp); 229 void MultiPushDoubles(RegList dregs, Register location = sp);
175 void MultiPopDoubles(RegList dregs, Register location = sp); 230 void MultiPopDoubles(RegList dregs, Register location = sp);
176 231
177 // Load an object from the root table. 232 // Load an object from the root table.
178 void LoadRoot(Register destination, Heap::RootListIndex index, 233 void LoadRoot(Register destination, Heap::RootListIndex index,
179 Condition cond = al); 234 Condition cond = al);
180 // Store an object to the root table. 235 // Store an object to the root table.
181 void StoreRoot(Register source, Heap::RootListIndex index, 236 void StoreRoot(Register source, Heap::RootListIndex index,
182 Condition cond = al); 237 Condition cond = al);
183 238
239 //--------------------------------------------------------------------------
240 // S390 Macro Assemblers for Instructions
241 //--------------------------------------------------------------------------
242
243 // Arithmetic Operations
244
245 // Add (Register - Immediate)
246 void Add32(Register dst, const Operand& imm);
247 void AddP(Register dst, const Operand& imm);
248 void Add32(Register dst, Register src, const Operand& imm);
249 void AddP(Register dst, Register src, const Operand& imm);
250
251 // Add (Register - Register)
252 void Add32(Register dst, Register src);
253 void AddP(Register dst, Register src);
254 void AddP_ExtendSrc(Register dst, Register src);
255 void Add32(Register dst, Register src1, Register src2);
256 void AddP(Register dst, Register src1, Register src2);
257 void AddP_ExtendSrc(Register dst, Register src1, Register src2);
258
259 // Add (Register - Mem)
260 void Add32(Register dst, const MemOperand& opnd);
261 void AddP(Register dst, const MemOperand& opnd);
262 void AddP_ExtendSrc(Register dst, const MemOperand& opnd);
263
264 // Add (Mem - Immediate)
265 void Add32(const MemOperand& opnd, const Operand& imm);
266 void AddP(const MemOperand& opnd, const Operand& imm);
267
268 // Add Logical (Register - Immediate)
269 void AddLogical(Register dst, const Operand& imm);
270 void AddLogicalP(Register dst, const Operand& imm);
271
272 // Add Logical (Register - Mem)
273 void AddLogical(Register dst, const MemOperand& opnd);
274 void AddLogicalP(Register dst, const MemOperand& opnd);
275
276 // Subtract (Register - Immediate)
277 void Sub32(Register dst, const Operand& imm);
278 void SubP(Register dst, const Operand& imm);
279 void Sub32(Register dst, Register src, const Operand& imm);
280 void SubP(Register dst, Register src, const Operand& imm);
281
282 // Subtract (Register - Register)
283 void Sub32(Register dst, Register src);
284 void SubP(Register dst, Register src);
285 void SubP_ExtendSrc(Register dst, Register src);
286 void Sub32(Register dst, Register src1, Register src2);
287 void SubP(Register dst, Register src1, Register src2);
288 void SubP_ExtendSrc(Register dst, Register src1, Register src2);
289
290 // Subtract (Register - Mem)
291 void Sub32(Register dst, const MemOperand& opnd);
292 void SubP(Register dst, const MemOperand& opnd);
293 void SubP_ExtendSrc(Register dst, const MemOperand& opnd);
294
295 // Subtract Logical (Register - Mem)
296 void SubLogical(Register dst, const MemOperand& opnd);
297 void SubLogicalP(Register dst, const MemOperand& opnd);
298 void SubLogicalP_ExtendSrc(Register dst, const MemOperand& opnd);
299
300 // Multiply
301 void MulP(Register dst, const Operand& opnd);
302 void MulP(Register dst, Register src);
303 void MulP(Register dst, const MemOperand& opnd);
304 void Mul(Register dst, Register src1, Register src2);
305
306 // Divide
307 void DivP(Register dividend, Register divider);
308
309 // Compare
310 void Cmp32(Register src1, Register src2);
311 void CmpP(Register src1, Register src2);
312 void Cmp32(Register dst, const Operand& opnd);
313 void CmpP(Register dst, const Operand& opnd);
314 void Cmp32(Register dst, const MemOperand& opnd);
315 void CmpP(Register dst, const MemOperand& opnd);
316
317 // Compare Logical
318 void CmpLogical32(Register src1, Register src2);
319 void CmpLogicalP(Register src1, Register src2);
320 void CmpLogical32(Register src1, const Operand& opnd);
321 void CmpLogicalP(Register src1, const Operand& opnd);
322 void CmpLogical32(Register dst, const MemOperand& opnd);
323 void CmpLogicalP(Register dst, const MemOperand& opnd);
324
325 // Compare Logical Byte (CLI/CLIY)
326 void CmpLogicalByte(const MemOperand& mem, const Operand& imm);
327
328 // Load 32bit
329 void Load(Register dst, const MemOperand& opnd);
330 void Load(Register dst, const Operand& opnd);
331 void LoadW(Register dst, const MemOperand& opnd, Register scratch = no_reg);
332 void LoadlW(Register dst, const MemOperand& opnd, Register scratch = no_reg);
333 void LoadB(Register dst, const MemOperand& opnd);
334 void LoadlB(Register dst, const MemOperand& opnd);
335
336 // Load And Test
337 void LoadAndTest32(Register dst, Register src);
338 void LoadAndTestP_ExtendSrc(Register dst, Register src);
339 void LoadAndTestP(Register dst, Register src);
340
341 void LoadAndTest32(Register dst, const MemOperand& opnd);
342 void LoadAndTestP(Register dst, const MemOperand& opnd);
343
344 // Load Floating Point
345 void LoadDouble(DoubleRegister dst, const MemOperand& opnd);
346 void LoadFloat32(DoubleRegister dst, const MemOperand& opnd);
347 void LoadFloat32ConvertToDouble(DoubleRegister dst, const MemOperand& mem);
348
349 // Store Floating Point
350 void StoreDouble(DoubleRegister dst, const MemOperand& opnd);
351 void StoreFloat32(DoubleRegister dst, const MemOperand& opnd);
352 void StoreDoubleAsFloat32(DoubleRegister src, const MemOperand& mem,
353 DoubleRegister scratch);
354
355 void Branch(Condition c, const Operand& opnd);
356 void BranchOnCount(Register r1, Label* l);
357
358 // Shifts
359 void ShiftLeft(Register dst, Register src, Register val);
360 void ShiftLeft(Register dst, Register src, const Operand& val);
361 void ShiftRight(Register dst, Register src, Register val);
362 void ShiftRight(Register dst, Register src, const Operand& val);
363 void ShiftLeftArith(Register dst, Register src, Register shift);
364 void ShiftLeftArith(Register dst, Register src, const Operand& val);
365 void ShiftRightArith(Register dst, Register src, Register shift);
366 void ShiftRightArith(Register dst, Register src, const Operand& val);
367
368 void ClearRightImm(Register dst, Register src, const Operand& val);
369
370 // Bitwise operations
371 void And(Register dst, Register src);
372 void AndP(Register dst, Register src);
373 void And(Register dst, Register src1, Register src2);
374 void AndP(Register dst, Register src1, Register src2);
375 void And(Register dst, const MemOperand& opnd);
376 void AndP(Register dst, const MemOperand& opnd);
377 void And(Register dst, const Operand& opnd);
378 void AndP(Register dst, const Operand& opnd);
379 void And(Register dst, Register src, const Operand& opnd);
380 void AndP(Register dst, Register src, const Operand& opnd);
381 void Or(Register dst, Register src);
382 void OrP(Register dst, Register src);
383 void Or(Register dst, Register src1, Register src2);
384 void OrP(Register dst, Register src1, Register src2);
385 void Or(Register dst, const MemOperand& opnd);
386 void OrP(Register dst, const MemOperand& opnd);
387 void Or(Register dst, const Operand& opnd);
388 void OrP(Register dst, const Operand& opnd);
389 void Or(Register dst, Register src, const Operand& opnd);
390 void OrP(Register dst, Register src, const Operand& opnd);
391 void Xor(Register dst, Register src);
392 void XorP(Register dst, Register src);
393 void Xor(Register dst, Register src1, Register src2);
394 void XorP(Register dst, Register src1, Register src2);
395 void Xor(Register dst, const MemOperand& opnd);
396 void XorP(Register dst, const MemOperand& opnd);
397 void Xor(Register dst, const Operand& opnd);
398 void XorP(Register dst, const Operand& opnd);
399 void Xor(Register dst, Register src, const Operand& opnd);
400 void XorP(Register dst, Register src, const Operand& opnd);
401 void Popcnt32(Register dst, Register src);
402
403 #ifdef V8_TARGET_ARCH_S390X
404 void Popcnt64(Register dst, Register src);
405 #endif
406
407 void NotP(Register dst);
408
409 void mov(Register dst, const Operand& src);
410
184 // --------------------------------------------------------------------------- 411 // ---------------------------------------------------------------------------
185 // GC Support 412 // GC Support
186 413
187 void IncrementalMarkingRecordWriteHelper(Register object, Register value, 414 void IncrementalMarkingRecordWriteHelper(Register object, Register value,
188 Register address); 415 Register address);
189 416
190 enum RememberedSetFinalAction { kReturnAtEnd, kFallThroughAtEnd }; 417 enum RememberedSetFinalAction { kReturnAtEnd, kFallThroughAtEnd };
191 418
192 // Record in the remembered set the fact that we have a pointer to new space 419 // Record in the remembered set the fact that we have a pointer to new space
193 // at the address pointed to by the addr register. Only works if addr is not 420 // at the address pointed to by the addr register. Only works if addr is not
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 // has been written. |value| is the object being stored. The value and 490 // has been written. |value| is the object being stored. The value and
264 // address registers are clobbered by the operation. 491 // address registers are clobbered by the operation.
265 void RecordWrite( 492 void RecordWrite(
266 Register object, Register address, Register value, 493 Register object, Register address, Register value,
267 LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, 494 LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
268 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 495 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
269 SmiCheck smi_check = INLINE_SMI_CHECK, 496 SmiCheck smi_check = INLINE_SMI_CHECK,
270 PointersToHereCheck pointers_to_here_check_for_value = 497 PointersToHereCheck pointers_to_here_check_for_value =
271 kPointersToHereMaybeInteresting); 498 kPointersToHereMaybeInteresting);
272 499
500 void push(Register src) {
501 lay(sp, MemOperand(sp, -kPointerSize));
502 StoreP(src, MemOperand(sp));
503 }
504
505 void pop(Register dst) {
506 LoadP(dst, MemOperand(sp));
507 la(sp, MemOperand(sp, kPointerSize));
508 }
509
510 void pop() { la(sp, MemOperand(sp, kPointerSize)); }
511
273 void Push(Register src) { push(src); } 512 void Push(Register src) { push(src); }
274 513
275 // Push a handle. 514 // Push a handle.
276 void Push(Handle<Object> handle); 515 void Push(Handle<Object> handle);
277 void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); } 516 void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
278 517
279 // Push two registers. Pushes leftmost register first (to highest address). 518 // Push two registers. Pushes leftmost register first (to highest address).
280 void Push(Register src1, Register src2) { 519 void Push(Register src1, Register src2) {
281 StorePU(src2, MemOperand(sp, -2 * kPointerSize)); 520 lay(sp, MemOperand(sp, -kPointerSize * 2));
282 StoreP(src1, MemOperand(sp, kPointerSize)); 521 StoreP(src1, MemOperand(sp, kPointerSize));
522 StoreP(src2, MemOperand(sp, 0));
283 } 523 }
284 524
285 // Push three registers. Pushes leftmost register first (to highest address). 525 // Push three registers. Pushes leftmost register first (to highest address).
286 void Push(Register src1, Register src2, Register src3) { 526 void Push(Register src1, Register src2, Register src3) {
287 StorePU(src3, MemOperand(sp, -3 * kPointerSize)); 527 lay(sp, MemOperand(sp, -kPointerSize * 3));
528 StoreP(src1, MemOperand(sp, kPointerSize * 2));
288 StoreP(src2, MemOperand(sp, kPointerSize)); 529 StoreP(src2, MemOperand(sp, kPointerSize));
289 StoreP(src1, MemOperand(sp, 2 * kPointerSize)); 530 StoreP(src3, MemOperand(sp, 0));
290 } 531 }
291 532
292 // Push four registers. Pushes leftmost register first (to highest address). 533 // Push four registers. Pushes leftmost register first (to highest address).
293 void Push(Register src1, Register src2, Register src3, Register src4) { 534 void Push(Register src1, Register src2, Register src3, Register src4) {
294 StorePU(src4, MemOperand(sp, -4 * kPointerSize)); 535 lay(sp, MemOperand(sp, -kPointerSize * 4));
536 StoreP(src1, MemOperand(sp, kPointerSize * 3));
537 StoreP(src2, MemOperand(sp, kPointerSize * 2));
295 StoreP(src3, MemOperand(sp, kPointerSize)); 538 StoreP(src3, MemOperand(sp, kPointerSize));
296 StoreP(src2, MemOperand(sp, 2 * kPointerSize)); 539 StoreP(src4, MemOperand(sp, 0));
297 StoreP(src1, MemOperand(sp, 3 * kPointerSize));
298 } 540 }
299 541
300 // Push five registers. Pushes leftmost register first (to highest address). 542 // Push five registers. Pushes leftmost register first (to highest address).
301 void Push(Register src1, Register src2, Register src3, Register src4, 543 void Push(Register src1, Register src2, Register src3, Register src4,
302 Register src5) { 544 Register src5) {
303 StorePU(src5, MemOperand(sp, -5 * kPointerSize)); 545 DCHECK(!src1.is(src2));
546 DCHECK(!src1.is(src3));
547 DCHECK(!src2.is(src3));
548 DCHECK(!src1.is(src4));
549 DCHECK(!src2.is(src4));
550 DCHECK(!src3.is(src4));
551 DCHECK(!src1.is(src5));
552 DCHECK(!src2.is(src5));
553 DCHECK(!src3.is(src5));
554 DCHECK(!src4.is(src5));
555
556 lay(sp, MemOperand(sp, -kPointerSize * 5));
557 StoreP(src1, MemOperand(sp, kPointerSize * 4));
558 StoreP(src2, MemOperand(sp, kPointerSize * 3));
559 StoreP(src3, MemOperand(sp, kPointerSize * 2));
304 StoreP(src4, MemOperand(sp, kPointerSize)); 560 StoreP(src4, MemOperand(sp, kPointerSize));
305 StoreP(src3, MemOperand(sp, 2 * kPointerSize)); 561 StoreP(src5, MemOperand(sp, 0));
306 StoreP(src2, MemOperand(sp, 3 * kPointerSize));
307 StoreP(src1, MemOperand(sp, 4 * kPointerSize));
308 } 562 }
309 563
310 void Pop(Register dst) { pop(dst); } 564 void Pop(Register dst) { pop(dst); }
311 565
312 // Pop two registers. Pops rightmost register first (from lower address). 566 // Pop two registers. Pops rightmost register first (from lower address).
313 void Pop(Register src1, Register src2) { 567 void Pop(Register src1, Register src2) {
314 LoadP(src2, MemOperand(sp, 0)); 568 LoadP(src2, MemOperand(sp, 0));
315 LoadP(src1, MemOperand(sp, kPointerSize)); 569 LoadP(src1, MemOperand(sp, kPointerSize));
316 addi(sp, sp, Operand(2 * kPointerSize)); 570 la(sp, MemOperand(sp, 2 * kPointerSize));
317 } 571 }
318 572
319 // Pop three registers. Pops rightmost register first (from lower address). 573 // Pop three registers. Pops rightmost register first (from lower address).
320 void Pop(Register src1, Register src2, Register src3) { 574 void Pop(Register src1, Register src2, Register src3) {
321 LoadP(src3, MemOperand(sp, 0)); 575 LoadP(src3, MemOperand(sp, 0));
322 LoadP(src2, MemOperand(sp, kPointerSize)); 576 LoadP(src2, MemOperand(sp, kPointerSize));
323 LoadP(src1, MemOperand(sp, 2 * kPointerSize)); 577 LoadP(src1, MemOperand(sp, 2 * kPointerSize));
324 addi(sp, sp, Operand(3 * kPointerSize)); 578 la(sp, MemOperand(sp, 3 * kPointerSize));
325 } 579 }
326 580
327 // Pop four registers. Pops rightmost register first (from lower address). 581 // Pop four registers. Pops rightmost register first (from lower address).
328 void Pop(Register src1, Register src2, Register src3, Register src4) { 582 void Pop(Register src1, Register src2, Register src3, Register src4) {
329 LoadP(src4, MemOperand(sp, 0)); 583 LoadP(src4, MemOperand(sp, 0));
330 LoadP(src3, MemOperand(sp, kPointerSize)); 584 LoadP(src3, MemOperand(sp, kPointerSize));
331 LoadP(src2, MemOperand(sp, 2 * kPointerSize)); 585 LoadP(src2, MemOperand(sp, 2 * kPointerSize));
332 LoadP(src1, MemOperand(sp, 3 * kPointerSize)); 586 LoadP(src1, MemOperand(sp, 3 * kPointerSize));
333 addi(sp, sp, Operand(4 * kPointerSize)); 587 la(sp, MemOperand(sp, 4 * kPointerSize));
334 } 588 }
335 589
336 // Pop five registers. Pops rightmost register first (from lower address). 590 // Pop five registers. Pops rightmost register first (from lower address).
337 void Pop(Register src1, Register src2, Register src3, Register src4, 591 void Pop(Register src1, Register src2, Register src3, Register src4,
338 Register src5) { 592 Register src5) {
339 LoadP(src5, MemOperand(sp, 0)); 593 LoadP(src5, MemOperand(sp, 0));
340 LoadP(src4, MemOperand(sp, kPointerSize)); 594 LoadP(src4, MemOperand(sp, kPointerSize));
341 LoadP(src3, MemOperand(sp, 2 * kPointerSize)); 595 LoadP(src3, MemOperand(sp, 2 * kPointerSize));
342 LoadP(src2, MemOperand(sp, 3 * kPointerSize)); 596 LoadP(src2, MemOperand(sp, 3 * kPointerSize));
343 LoadP(src1, MemOperand(sp, 4 * kPointerSize)); 597 LoadP(src1, MemOperand(sp, 4 * kPointerSize));
344 addi(sp, sp, Operand(5 * kPointerSize)); 598 la(sp, MemOperand(sp, 5 * kPointerSize));
345 } 599 }
346 600
347 // Push a fixed frame, consisting of lr, fp, context and 601 // Push a fixed frame, consisting of lr, fp, context and
348 // JS function / marker id if marker_reg is a valid register. 602 // JS function / marker id if marker_reg is a valid register.
349 void PushFixedFrame(Register marker_reg = no_reg); 603 void PushFixedFrame(Register marker_reg = no_reg);
350 void PopFixedFrame(Register marker_reg = no_reg); 604 void PopFixedFrame(Register marker_reg = no_reg);
351 605
352 // Restore caller's frame pointer and return address prior to being 606 // Restore caller's frame pointer and return address prior to being
353 // overwritten by tail call stack preparation. 607 // overwritten by tail call stack preparation.
354 void RestoreFrameStateForTailCall(); 608 void RestoreFrameStateForTailCall();
(...skipping 29 matching lines...) Expand all
384 void ConvertUnsignedIntToDouble(Register src, DoubleRegister dst); 638 void ConvertUnsignedIntToDouble(Register src, DoubleRegister dst);
385 639
386 // Converts the integer (untagged smi) in |src| to 640 // Converts the integer (untagged smi) in |src| to
387 // a float, storing the result in |dst| 641 // a float, storing the result in |dst|
388 void ConvertIntToFloat(Register src, DoubleRegister dst); 642 void ConvertIntToFloat(Register src, DoubleRegister dst);
389 643
390 // Converts the unsigned integer (untagged smi) in |src| to 644 // Converts the unsigned integer (untagged smi) in |src| to
391 // a float, storing the result in |dst| 645 // a float, storing the result in |dst|
392 void ConvertUnsignedIntToFloat(Register src, DoubleRegister dst); 646 void ConvertUnsignedIntToFloat(Register src, DoubleRegister dst);
393 647
394 #if V8_TARGET_ARCH_PPC64 648 #if V8_TARGET_ARCH_S390X
395 void ConvertInt64ToFloat(Register src, DoubleRegister double_dst); 649 void ConvertInt64ToFloat(Register src, DoubleRegister double_dst);
396 void ConvertInt64ToDouble(Register src, DoubleRegister double_dst); 650 void ConvertInt64ToDouble(Register src, DoubleRegister double_dst);
397 void ConvertUnsignedInt64ToFloat(Register src, DoubleRegister double_dst); 651 void ConvertUnsignedInt64ToFloat(Register src, DoubleRegister double_dst);
398 void ConvertUnsignedInt64ToDouble(Register src, DoubleRegister double_dst); 652 void ConvertUnsignedInt64ToDouble(Register src, DoubleRegister double_dst);
399 #endif 653 #endif
400 654
655 void MovIntToFloat(DoubleRegister dst, Register src);
656 void MovFloatToInt(Register dst, DoubleRegister src);
657 void MovDoubleToInt64(Register dst, DoubleRegister src);
658 void MovInt64ToDouble(DoubleRegister dst, Register src);
659 // Converts the double_input to an integer. Note that, upon return,
660 // the contents of double_dst will also hold the fixed point representation.
661 void ConvertFloat32ToInt64(const DoubleRegister double_input,
662 #if !V8_TARGET_ARCH_S390X
663 const Register dst_hi,
664 #endif
665 const Register dst,
666 const DoubleRegister double_dst,
667 FPRoundingMode rounding_mode = kRoundToZero);
668
401 // Converts the double_input to an integer. Note that, upon return, 669 // Converts the double_input to an integer. Note that, upon return,
402 // the contents of double_dst will also hold the fixed point representation. 670 // the contents of double_dst will also hold the fixed point representation.
403 void ConvertDoubleToInt64(const DoubleRegister double_input, 671 void ConvertDoubleToInt64(const DoubleRegister double_input,
404 #if !V8_TARGET_ARCH_PPC64 672 #if !V8_TARGET_ARCH_S390X
405 const Register dst_hi, 673 const Register dst_hi,
406 #endif 674 #endif
407 const Register dst, const DoubleRegister double_dst, 675 const Register dst, const DoubleRegister double_dst,
408 FPRoundingMode rounding_mode = kRoundToZero); 676 FPRoundingMode rounding_mode = kRoundToZero);
409 677
410 #if V8_TARGET_ARCH_PPC64 678 void ConvertFloat32ToInt32(const DoubleRegister double_input,
679 const Register dst,
680 const DoubleRegister double_dst,
681 FPRoundingMode rounding_mode = kRoundToZero);
682 void ConvertFloat32ToUnsignedInt32(
683 const DoubleRegister double_input, const Register dst,
684 const DoubleRegister double_dst,
685 FPRoundingMode rounding_mode = kRoundToZero);
686 #if V8_TARGET_ARCH_S390X
411 // Converts the double_input to an unsigned integer. Note that, upon return, 687 // Converts the double_input to an unsigned integer. Note that, upon return,
412 // the contents of double_dst will also hold the fixed point representation. 688 // the contents of double_dst will also hold the fixed point representation.
413 void ConvertDoubleToUnsignedInt64( 689 void ConvertDoubleToUnsignedInt64(
414 const DoubleRegister double_input, const Register dst, 690 const DoubleRegister double_input, const Register dst,
415 const DoubleRegister double_dst, 691 const DoubleRegister double_dst,
416 FPRoundingMode rounding_mode = kRoundToZero); 692 FPRoundingMode rounding_mode = kRoundToZero);
693 void ConvertFloat32ToUnsignedInt64(
694 const DoubleRegister double_input, const Register dst,
695 const DoubleRegister double_dst,
696 FPRoundingMode rounding_mode = kRoundToZero);
417 #endif 697 #endif
418 698
419 // Generates function and stub prologue code. 699 // Generates function and stub prologue code.
420 void StubPrologue(Register base = no_reg, int prologue_offset = 0); 700 void StubPrologue(Register base = no_reg, int prologue_offset = 0);
421 void Prologue(bool code_pre_aging, Register base, int prologue_offset = 0); 701 void Prologue(bool code_pre_aging, Register base, int prologue_offset = 0);
422 702
423 // Enter exit frame. 703 // Enter exit frame.
424 // stack_space - extra stack space, used for parameters before call to C. 704 // stack_space - extra stack space, used for parameters before call to C.
425 // At least one slot (for the return address) should be provided. 705 // At least one slot (for the return address) should be provided.
426 void EnterExitFrame(bool save_doubles, int stack_space = 1); 706 void EnterExitFrame(bool save_doubles, int stack_space = 1);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 void LoadGlobalFunctionInitialMap(Register function, Register map, 744 void LoadGlobalFunctionInitialMap(Register function, Register map,
465 Register scratch); 745 Register scratch);
466 746
467 void InitializeRootRegister() { 747 void InitializeRootRegister() {
468 ExternalReference roots_array_start = 748 ExternalReference roots_array_start =
469 ExternalReference::roots_array_start(isolate()); 749 ExternalReference::roots_array_start(isolate());
470 mov(kRootRegister, Operand(roots_array_start)); 750 mov(kRootRegister, Operand(roots_array_start));
471 } 751 }
472 752
473 // ---------------------------------------------------------------- 753 // ----------------------------------------------------------------
474 // new PPC macro-assembler interfaces that are slightly higher level 754 // new S390 macro-assembler interfaces that are slightly higher level
475 // than assembler-ppc and may generate variable length sequences 755 // than assembler-s390 and may generate variable length sequences
476 756
477 // load a literal signed int value <value> to GPR <dst> 757 // load a literal signed int value <value> to GPR <dst>
478 void LoadIntLiteral(Register dst, int value); 758 void LoadIntLiteral(Register dst, int value);
479 759
480 // load an SMI value <value> to GPR <dst> 760 // load an SMI value <value> to GPR <dst>
481 void LoadSmiLiteral(Register dst, Smi* smi); 761 void LoadSmiLiteral(Register dst, Smi* smi);
482 762
483 // load a literal double value <value> to FPR <result> 763 // load a literal double value <value> to FPR <result>
484 void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch); 764 void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch);
765 void LoadDoubleLiteral(DoubleRegister result, uint64_t value,
766 Register scratch);
485 767
486 void LoadWord(Register dst, const MemOperand& mem, Register scratch); 768 void LoadFloat32Literal(DoubleRegister result, float value, Register scratch);
487 void LoadWordArith(Register dst, const MemOperand& mem, 769
770 void StoreW(Register src, const MemOperand& mem, Register scratch = no_reg);
771
772 void LoadHalfWordP(Register dst, const MemOperand& mem,
488 Register scratch = no_reg); 773 Register scratch = no_reg);
489 void StoreWord(Register src, const MemOperand& mem, Register scratch);
490 774
491 void LoadHalfWord(Register dst, const MemOperand& mem, Register scratch); 775 void StoreHalfWord(Register src, const MemOperand& mem,
492 void LoadHalfWordArith(Register dst, const MemOperand& mem, 776 Register scratch = r0);
493 Register scratch = no_reg); 777 void StoreByte(Register src, const MemOperand& mem, Register scratch = r0);
494 void StoreHalfWord(Register src, const MemOperand& mem, Register scratch);
495
496 void LoadByte(Register dst, const MemOperand& mem, Register scratch);
497 void StoreByte(Register src, const MemOperand& mem, Register scratch);
498 778
499 void LoadRepresentation(Register dst, const MemOperand& mem, Representation r, 779 void LoadRepresentation(Register dst, const MemOperand& mem, Representation r,
500 Register scratch = no_reg); 780 Register scratch = no_reg);
501 void StoreRepresentation(Register src, const MemOperand& mem, 781 void StoreRepresentation(Register src, const MemOperand& mem,
502 Representation r, Register scratch = no_reg); 782 Representation r, Register scratch = no_reg);
503 783
504 void LoadDouble(DoubleRegister dst, const MemOperand& mem, Register scratch);
505 void StoreDouble(DoubleRegister src, const MemOperand& mem, Register scratch);
506
507 // Move values between integer and floating point registers.
508 void MovIntToDouble(DoubleRegister dst, Register src, Register scratch);
509 void MovUnsignedIntToDouble(DoubleRegister dst, Register src,
510 Register scratch);
511 void MovInt64ToDouble(DoubleRegister dst,
512 #if !V8_TARGET_ARCH_PPC64
513 Register src_hi,
514 #endif
515 Register src);
516 #if V8_TARGET_ARCH_PPC64
517 void MovInt64ComponentsToDouble(DoubleRegister dst, Register src_hi,
518 Register src_lo, Register scratch);
519 #endif
520 void InsertDoubleLow(DoubleRegister dst, Register src, Register scratch);
521 void InsertDoubleHigh(DoubleRegister dst, Register src, Register scratch);
522 void MovDoubleLowToInt(Register dst, DoubleRegister src);
523 void MovDoubleHighToInt(Register dst, DoubleRegister src);
524 void MovDoubleToInt64(
525 #if !V8_TARGET_ARCH_PPC64
526 Register dst_hi,
527 #endif
528 Register dst, DoubleRegister src);
529 void MovIntToFloat(DoubleRegister dst, Register src);
530 void MovFloatToInt(Register dst, DoubleRegister src);
531
532 void Add(Register dst, Register src, intptr_t value, Register scratch);
533 void Cmpi(Register src1, const Operand& src2, Register scratch,
534 CRegister cr = cr7);
535 void Cmpli(Register src1, const Operand& src2, Register scratch,
536 CRegister cr = cr7);
537 void Cmpwi(Register src1, const Operand& src2, Register scratch,
538 CRegister cr = cr7);
539 void Cmplwi(Register src1, const Operand& src2, Register scratch,
540 CRegister cr = cr7);
541 void And(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
542 void Or(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
543 void Xor(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
544
545 void AddSmiLiteral(Register dst, Register src, Smi* smi, Register scratch); 784 void AddSmiLiteral(Register dst, Register src, Smi* smi, Register scratch);
546 void SubSmiLiteral(Register dst, Register src, Smi* smi, Register scratch); 785 void SubSmiLiteral(Register dst, Register src, Smi* smi, Register scratch);
547 void CmpSmiLiteral(Register src1, Smi* smi, Register scratch, 786 void CmpSmiLiteral(Register src1, Smi* smi, Register scratch);
548 CRegister cr = cr7); 787 void CmpLogicalSmiLiteral(Register src1, Smi* smi, Register scratch);
549 void CmplSmiLiteral(Register src1, Smi* smi, Register scratch, 788 void AndSmiLiteral(Register dst, Register src, Smi* smi);
550 CRegister cr = cr7);
551 void AndSmiLiteral(Register dst, Register src, Smi* smi, Register scratch,
552 RCBit rc = LeaveRC);
553 789
554 // Set new rounding mode RN to FPSCR 790 // Set new rounding mode RN to FPSCR
555 void SetRoundingMode(FPRoundingMode RN); 791 void SetRoundingMode(FPRoundingMode RN);
556 792
557 // reset rounding mode to default (kRoundToNearest) 793 // reset rounding mode to default (kRoundToNearest)
558 void ResetRoundingMode(); 794 void ResetRoundingMode();
559 795
560 // These exist to provide portability between 32 and 64bit 796 // These exist to provide portability between 32 and 64bit
561 void LoadP(Register dst, const MemOperand& mem, Register scratch = no_reg); 797 void LoadP(Register dst, const MemOperand& mem, Register scratch = no_reg);
562 void StoreP(Register src, const MemOperand& mem, Register scratch = no_reg); 798 void StoreP(Register src, const MemOperand& mem, Register scratch = no_reg);
799 void StoreP(const MemOperand& mem, const Operand& opnd,
800 Register scratch = no_reg);
801 void LoadMultipleP(Register dst1, Register dst2, const MemOperand& mem);
802 void StoreMultipleP(Register dst1, Register dst2, const MemOperand& mem);
803 void LoadMultipleW(Register dst1, Register dst2, const MemOperand& mem);
804 void StoreMultipleW(Register dst1, Register dst2, const MemOperand& mem);
805
806 // Cleanse pointer address on 31bit by zero out top bit.
807 // This is a NOP on 64-bit.
808 void CleanseP(Register src) {
809 #if (V8_HOST_ARCH_S390 && !(V8_TARGET_ARCH_S390X))
810 nilh(src, Operand(0x7FFF));
811 #endif
812 }
563 813
564 // --------------------------------------------------------------------------- 814 // ---------------------------------------------------------------------------
565 // JavaScript invokes 815 // JavaScript invokes
566 816
817 // Set up call kind marking in ecx. The method takes ecx as an
818 // explicit first parameter to make the code more readable at the
819 // call sites.
820 // void SetCallKind(Register dst, CallKind kind);
821
567 // Invoke the JavaScript function code by either calling or jumping. 822 // Invoke the JavaScript function code by either calling or jumping.
568 void InvokeFunctionCode(Register function, Register new_target, 823 void InvokeFunctionCode(Register function, Register new_target,
569 const ParameterCount& expected, 824 const ParameterCount& expected,
570 const ParameterCount& actual, InvokeFlag flag, 825 const ParameterCount& actual, InvokeFlag flag,
571 const CallWrapper& call_wrapper); 826 const CallWrapper& call_wrapper);
572 827
573 void FloodFunctionIfStepping(Register fun, Register new_target, 828 void FloodFunctionIfStepping(Register fun, Register new_target,
574 const ParameterCount& expected, 829 const ParameterCount& expected,
575 const ParameterCount& actual); 830 const ParameterCount& actual);
576 831
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 // is left untouched, whereas both scratch registers are clobbered. 871 // is left untouched, whereas both scratch registers are clobbered.
617 void CheckAccessGlobalProxy(Register holder_reg, Register scratch, 872 void CheckAccessGlobalProxy(Register holder_reg, Register scratch,
618 Label* miss); 873 Label* miss);
619 874
620 void GetNumberHash(Register t0, Register scratch); 875 void GetNumberHash(Register t0, Register scratch);
621 876
622 void LoadFromNumberDictionary(Label* miss, Register elements, Register key, 877 void LoadFromNumberDictionary(Label* miss, Register elements, Register key,
623 Register result, Register t0, Register t1, 878 Register result, Register t0, Register t1,
624 Register t2); 879 Register t2);
625 880
626
627 inline void MarkCode(NopMarkerTypes type) { nop(type); } 881 inline void MarkCode(NopMarkerTypes type) { nop(type); }
628 882
629 // Check if the given instruction is a 'type' marker. 883 // Check if the given instruction is a 'type' marker.
630 // i.e. check if is is a mov r<type>, r<type> (referenced as nop(type)) 884 // i.e. check if is is a mov r<type>, r<type> (referenced as nop(type))
631 // These instructions are generated to mark special location in the code, 885 // These instructions are generated to mark special location in the code,
632 // like some special IC code. 886 // like some special IC code.
633 static inline bool IsMarkedCode(Instr instr, int type) { 887 static inline bool IsMarkedCode(Instr instr, int type) {
634 DCHECK((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)); 888 DCHECK((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
635 return IsNop(instr, type); 889 return IsNop(instr, type);
636 } 890 }
637 891
638
639 static inline int GetCodeMarker(Instr instr) { 892 static inline int GetCodeMarker(Instr instr) {
640 int dst_reg_offset = 12; 893 int dst_reg_offset = 12;
641 int dst_mask = 0xf << dst_reg_offset; 894 int dst_mask = 0xf << dst_reg_offset;
642 int src_mask = 0xf; 895 int src_mask = 0xf;
643 int dst_reg = (instr & dst_mask) >> dst_reg_offset; 896 int dst_reg = (instr & dst_mask) >> dst_reg_offset;
644 int src_reg = instr & src_mask; 897 int src_reg = instr & src_mask;
645 uint32_t non_register_mask = ~(dst_mask | src_mask); 898 uint32_t non_register_mask = ~(dst_mask | src_mask);
646 uint32_t mov_mask = al | 13 << 21; 899 uint32_t mov_mask = al | 13 << 21;
647 900
648 // Return <n> if we have a mov rn rn, else return -1. 901 // Return <n> if we have a mov rn rn, else return -1.
649 int type = ((instr & non_register_mask) == mov_mask) && 902 int type = ((instr & non_register_mask) == mov_mask) &&
650 (dst_reg == src_reg) && (FIRST_IC_MARKER <= dst_reg) && 903 (dst_reg == src_reg) && (FIRST_IC_MARKER <= dst_reg) &&
651 (dst_reg < LAST_CODE_MARKER) 904 (dst_reg < LAST_CODE_MARKER)
652 ? src_reg 905 ? src_reg
653 : -1; 906 : -1;
654 DCHECK((type == -1) || 907 DCHECK((type == -1) ||
655 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER))); 908 ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
656 return type; 909 return type;
657 } 910 }
658 911
659
660 // --------------------------------------------------------------------------- 912 // ---------------------------------------------------------------------------
661 // Allocation support 913 // Allocation support
662 914
663 // Allocate an object in new space or old space. The object_size is 915 // Allocate an object in new space or old pointer space. The object_size is
664 // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS 916 // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
665 // is passed. If the space is exhausted control continues at the gc_required 917 // is passed. If the space is exhausted control continues at the gc_required
666 // label. The allocated object is returned in result. If the flag 918 // label. The allocated object is returned in result. If the flag
667 // tag_allocated_object is true the result is tagged as as a heap object. 919 // tag_allocated_object is true the result is tagged as as a heap object.
668 // All registers are clobbered also when control continues at the gc_required 920 // All registers are clobbered also when control continues at the gc_required
669 // label. 921 // label.
670 void Allocate(int object_size, Register result, Register scratch1, 922 void Allocate(int object_size, Register result, Register scratch1,
671 Register scratch2, Label* gc_required, AllocationFlags flags); 923 Register scratch2, Label* gc_required, AllocationFlags flags);
672 924
673 void Allocate(Register object_size, Register result, Register result_end, 925 void Allocate(Register object_size, Register result, Register result_end,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 // other registers. 1005 // other registers.
754 // Type_reg can be no_reg. In that case ip is used. 1006 // Type_reg can be no_reg. In that case ip is used.
755 void CompareObjectType(Register heap_object, Register map, Register type_reg, 1007 void CompareObjectType(Register heap_object, Register map, Register type_reg,
756 InstanceType type); 1008 InstanceType type);
757 1009
758 // Compare instance type in a map. map contains a valid map object whose 1010 // Compare instance type in a map. map contains a valid map object whose
759 // object type should be compared with the given type. This both 1011 // object type should be compared with the given type. This both
760 // sets the flags and leaves the object type in the type_reg register. 1012 // sets the flags and leaves the object type in the type_reg register.
761 void CompareInstanceType(Register map, Register type_reg, InstanceType type); 1013 void CompareInstanceType(Register map, Register type_reg, InstanceType type);
762 1014
763
764 // Check if a map for a JSObject indicates that the object has fast elements. 1015 // Check if a map for a JSObject indicates that the object has fast elements.
765 // Jump to the specified label if it does not. 1016 // Jump to the specified label if it does not.
766 void CheckFastElements(Register map, Register scratch, Label* fail); 1017 void CheckFastElements(Register map, Register scratch, Label* fail);
767 1018
768 // Check if a map for a JSObject indicates that the object can have both smi 1019 // Check if a map for a JSObject indicates that the object can have both smi
769 // and HeapObject elements. Jump to the specified label if it does not. 1020 // and HeapObject elements. Jump to the specified label if it does not.
770 void CheckFastObjectElements(Register map, Register scratch, Label* fail); 1021 void CheckFastObjectElements(Register map, Register scratch, Label* fail);
771 1022
772 // Check if a map for a JSObject indicates that the object has fast smi only 1023 // Check if a map for a JSObject indicates that the object has fast smi only
773 // elements. Jump to the specified label if it does not. 1024 // elements. Jump to the specified label if it does not.
(...skipping 18 matching lines...) Expand all
792 // which is preserved by the code generated. 1043 // which is preserved by the code generated.
793 void CompareMap(Register obj_map, Handle<Map> map, Label* early_success); 1044 void CompareMap(Register obj_map, Handle<Map> map, Label* early_success);
794 1045
795 // Check if the map of an object is equal to a specified map and branch to 1046 // Check if the map of an object is equal to a specified map and branch to
796 // label if not. Skip the smi check if not required (object is known to be a 1047 // label if not. Skip the smi check if not required (object is known to be a
797 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 1048 // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
798 // against maps that are ElementsKind transition maps of the specified map. 1049 // against maps that are ElementsKind transition maps of the specified map.
799 void CheckMap(Register obj, Register scratch, Handle<Map> map, Label* fail, 1050 void CheckMap(Register obj, Register scratch, Handle<Map> map, Label* fail,
800 SmiCheckType smi_check_type); 1051 SmiCheckType smi_check_type);
801 1052
802
803 void CheckMap(Register obj, Register scratch, Heap::RootListIndex index, 1053 void CheckMap(Register obj, Register scratch, Heap::RootListIndex index,
804 Label* fail, SmiCheckType smi_check_type); 1054 Label* fail, SmiCheckType smi_check_type);
805 1055
806
807 // Check if the map of an object is equal to a specified weak map and branch 1056 // Check if the map of an object is equal to a specified weak map and branch
808 // to a specified target if equal. Skip the smi check if not required 1057 // to a specified target if equal. Skip the smi check if not required
809 // (object is known to be a heap object) 1058 // (object is known to be a heap object)
810 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2, 1059 void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
811 Handle<WeakCell> cell, Handle<Code> success, 1060 Handle<WeakCell> cell, Handle<Code> success,
812 SmiCheckType smi_check_type); 1061 SmiCheckType smi_check_type);
813 1062
814 // Compare the given value and the value of weak cell. 1063 // Compare the given value and the value of weak cell.
815 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch, 1064 void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch,
816 CRegister cr = cr7); 1065 CRegister cr = cr7);
(...skipping 23 matching lines...) Expand all
840 Label* if_not_equal) { 1089 Label* if_not_equal) {
841 CompareRoot(with, index); 1090 CompareRoot(with, index);
842 bne(if_not_equal); 1091 bne(if_not_equal);
843 } 1092 }
844 1093
845 // Load and check the instance type of an object for being a string. 1094 // Load and check the instance type of an object for being a string.
846 // Loads the type into the second argument register. 1095 // Loads the type into the second argument register.
847 // Returns a condition that will be enabled if the object was a string. 1096 // Returns a condition that will be enabled if the object was a string.
848 Condition IsObjectStringType(Register obj, Register type) { 1097 Condition IsObjectStringType(Register obj, Register type) {
849 LoadP(type, FieldMemOperand(obj, HeapObject::kMapOffset)); 1098 LoadP(type, FieldMemOperand(obj, HeapObject::kMapOffset));
850 lbz(type, FieldMemOperand(type, Map::kInstanceTypeOffset)); 1099 LoadlB(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
851 andi(r0, type, Operand(kIsNotStringMask)); 1100 mov(r0, Operand(kIsNotStringMask));
1101 AndP(r0, type);
852 DCHECK_EQ(0u, kStringTag); 1102 DCHECK_EQ(0u, kStringTag);
853 return eq; 1103 return eq;
854 } 1104 }
855 1105
856
857 // Picks out an array index from the hash field. 1106 // Picks out an array index from the hash field.
858 // Register use: 1107 // Register use:
859 // hash - holds the index's hash. Clobbered. 1108 // hash - holds the index's hash. Clobbered.
860 // index - holds the overwritten index on exit. 1109 // index - holds the overwritten index on exit.
861 void IndexFromHash(Register hash, Register index); 1110 void IndexFromHash(Register hash, Register index);
862 1111
863 // Get the number of least significant bits from a register 1112 // Get the number of least significant bits from a register
864 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits); 1113 void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
865 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits); 1114 void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
866 1115
867 // Load the value of a smi object into a double register. 1116 // Load the value of a smi object into a FP double register. The register
1117 // scratch1 can be the same register as smi in which case smi will hold the
1118 // untagged value afterwards.
868 void SmiToDouble(DoubleRegister value, Register smi); 1119 void SmiToDouble(DoubleRegister value, Register smi);
869 1120
870 // Check if a double can be exactly represented as a signed 32-bit integer. 1121 // Check if a double can be exactly represented as a signed 32-bit integer.
871 // CR_EQ in cr7 is set if true. 1122 // CR_EQ in cr7 is set if true.
872 void TestDoubleIsInt32(DoubleRegister double_input, Register scratch1, 1123 void TestDoubleIsInt32(DoubleRegister double_input, Register scratch1,
873 Register scratch2, DoubleRegister double_scratch); 1124 Register scratch2, DoubleRegister double_scratch);
874 1125
875 // Check if a double is equal to -0.0. 1126 // Check if a double is equal to -0.0.
876 // CR_EQ in cr7 holds the result. 1127 // CR_EQ in cr7 holds the result.
877 void TestDoubleIsMinusZero(DoubleRegister input, Register scratch1, 1128 void TestDoubleIsMinusZero(DoubleRegister input, Register scratch1,
(...skipping 10 matching lines...) Expand all
888 Register scratch, DoubleRegister double_scratch); 1139 Register scratch, DoubleRegister double_scratch);
889 1140
890 // Floor a double and writes the value to the result register. 1141 // Floor a double and writes the value to the result register.
891 // Go to exact if the conversion is exact (to be able to test -0), 1142 // Go to exact if the conversion is exact (to be able to test -0),
892 // fall through calling code if an overflow occurred, else go to done. 1143 // fall through calling code if an overflow occurred, else go to done.
893 // In return, input_high is loaded with high bits of input. 1144 // In return, input_high is loaded with high bits of input.
894 void TryInt32Floor(Register result, DoubleRegister double_input, 1145 void TryInt32Floor(Register result, DoubleRegister double_input,
895 Register input_high, Register scratch, 1146 Register input_high, Register scratch,
896 DoubleRegister double_scratch, Label* done, Label* exact); 1147 DoubleRegister double_scratch, Label* done, Label* exact);
897 1148
1149 // Perform ceiling of float in input_register and store in double_output.
1150 void FloatCeiling32(DoubleRegister double_output, DoubleRegister double_input,
1151 Register scratch, DoubleRegister double_scratch);
1152
1153 // Perform floor of float in input_register and store in double_output.
1154 void FloatFloor32(DoubleRegister double_output, DoubleRegister double_input,
1155 Register scratch);
1156
1157 // Perform ceiling of double in input_register and store in double_output.
1158 void FloatCeiling64(DoubleRegister double_output, DoubleRegister double_input,
1159 Register scratch, DoubleRegister double_scratch);
1160
1161 // Perform floor of double in input_register and store in double_output.
1162 void FloatFloor64(DoubleRegister double_output, DoubleRegister double_input,
1163 Register scratch);
1164
898 // Performs a truncating conversion of a floating point number as used by 1165 // Performs a truncating conversion of a floating point number as used by
899 // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it 1166 // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
900 // succeeds, otherwise falls through if result is saturated. On return 1167 // succeeds, otherwise falls through if result is saturated. On return
901 // 'result' either holds answer, or is clobbered on fall through. 1168 // 'result' either holds answer, or is clobbered on fall through.
902 // 1169 //
903 // Only public for the test code in test-code-stubs-arm.cc. 1170 // Only public for the test code in test-code-stubs-arm.cc.
904 void TryInlineTruncateDoubleToI(Register result, DoubleRegister input, 1171 void TryInlineTruncateDoubleToI(Register result, DoubleRegister input,
905 Label* done); 1172 Label* done);
906 1173
907 // Performs a truncating conversion of a floating point number as used by 1174 // Performs a truncating conversion of a floating point number as used by
(...skipping 25 matching lines...) Expand all
933 Register overflow_dst, Register scratch = r0); 1200 Register overflow_dst, Register scratch = r0);
934 void AddAndCheckForOverflow(Register dst, Register left, intptr_t right, 1201 void AddAndCheckForOverflow(Register dst, Register left, intptr_t right,
935 Register overflow_dst, Register scratch = r0); 1202 Register overflow_dst, Register scratch = r0);
936 1203
937 // Compute dst = left - right, setting condition codes. dst may be same as 1204 // Compute dst = left - right, setting condition codes. dst may be same as
938 // either left or right (or a unique register). left and right must not be 1205 // either left or right (or a unique register). left and right must not be
939 // the same register. 1206 // the same register.
940 void SubAndCheckForOverflow(Register dst, Register left, Register right, 1207 void SubAndCheckForOverflow(Register dst, Register left, Register right,
941 Register overflow_dst, Register scratch = r0); 1208 Register overflow_dst, Register scratch = r0);
942 1209
943 void BranchOnOverflow(Label* label) { blt(label, cr0); } 1210 void BranchOnOverflow(Label* label) { blt(label /*, cr0*/); }
944 1211
945 void BranchOnNoOverflow(Label* label) { bge(label, cr0); } 1212 void BranchOnNoOverflow(Label* label) { bge(label /*, cr0*/); }
946 1213
947 void RetOnOverflow(void) { Ret(lt, cr0); } 1214 void RetOnOverflow(void) {
1215 Label label;
948 1216
949 void RetOnNoOverflow(void) { Ret(ge, cr0); } 1217 blt(&label /*, cr0*/);
1218 Ret();
1219 bind(&label);
1220 }
1221
1222 void RetOnNoOverflow(void) {
1223 Label label;
1224
1225 bge(&label /*, cr0*/);
1226 Ret();
1227 bind(&label);
1228 }
950 1229
951 // --------------------------------------------------------------------------- 1230 // ---------------------------------------------------------------------------
952 // Runtime calls 1231 // Runtime calls
953 1232
954 // Call a code stub. 1233 // Call a code stub.
955 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None(), 1234 void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None(),
956 Condition cond = al); 1235 Condition cond = al);
957 1236
958 // Call a code stub. 1237 // Call a code stub.
959 void TailCallStub(CodeStub* stub, Condition cond = al); 1238 void TailCallStub(CodeStub* stub, Condition cond = al);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 void MovFromFloatResult(DoubleRegister dst); 1305 void MovFromFloatResult(DoubleRegister dst);
1027 1306
1028 // Jump to a runtime routine. 1307 // Jump to a runtime routine.
1029 void JumpToExternalReference(const ExternalReference& builtin); 1308 void JumpToExternalReference(const ExternalReference& builtin);
1030 1309
1031 Handle<Object> CodeObject() { 1310 Handle<Object> CodeObject() {
1032 DCHECK(!code_object_.is_null()); 1311 DCHECK(!code_object_.is_null());
1033 return code_object_; 1312 return code_object_;
1034 } 1313 }
1035 1314
1036
1037 // Emit code for a truncating division by a constant. The dividend register is 1315 // Emit code for a truncating division by a constant. The dividend register is
1038 // unchanged and ip gets clobbered. Dividend and result must be different. 1316 // unchanged and ip gets clobbered. Dividend and result must be different.
1039 void TruncatingDiv(Register result, Register dividend, int32_t divisor); 1317 void TruncatingDiv(Register result, Register dividend, int32_t divisor);
1040 1318
1041 // --------------------------------------------------------------------------- 1319 // ---------------------------------------------------------------------------
1042 // StatsCounter support 1320 // StatsCounter support
1043 1321
1044 void SetCounter(StatsCounter* counter, int value, Register scratch1, 1322 void SetCounter(StatsCounter* counter, int value, Register scratch1,
1045 Register scratch2); 1323 Register scratch2);
1046 void IncrementCounter(StatsCounter* counter, int value, Register scratch1, 1324 void IncrementCounter(StatsCounter* counter, int value, Register scratch1,
1047 Register scratch2); 1325 Register scratch2);
1048 void DecrementCounter(StatsCounter* counter, int value, Register scratch1, 1326 void DecrementCounter(StatsCounter* counter, int value, Register scratch1,
1049 Register scratch2); 1327 Register scratch2);
1050 1328
1051
1052 // --------------------------------------------------------------------------- 1329 // ---------------------------------------------------------------------------
1053 // Debugging 1330 // Debugging
1054 1331
1055 // Calls Abort(msg) if the condition cond is not satisfied. 1332 // Calls Abort(msg) if the condition cond is not satisfied.
1056 // Use --debug_code to enable. 1333 // Use --debug_code to enable.
1057 void Assert(Condition cond, BailoutReason reason, CRegister cr = cr7); 1334 void Assert(Condition cond, BailoutReason reason, CRegister cr = cr7);
1058 void AssertFastElements(Register elements); 1335 void AssertFastElements(Register elements);
1059 1336
1060 // Like Assert(), but always enabled. 1337 // Like Assert(), but always enabled.
1061 void Check(Condition cond, BailoutReason reason, CRegister cr = cr7); 1338 void Check(Condition cond, BailoutReason reason, CRegister cr = cr7);
(...skipping 29 matching lines...) Expand all
1091 1368
1092 // --------------------------------------------------------------------------- 1369 // ---------------------------------------------------------------------------
1093 // Bit testing/extraction 1370 // Bit testing/extraction
1094 // 1371 //
1095 // Bit numbering is such that the least significant bit is bit 0 1372 // Bit numbering is such that the least significant bit is bit 0
1096 // (for consistency between 32/64-bit). 1373 // (for consistency between 32/64-bit).
1097 1374
1098 // Extract consecutive bits (defined by rangeStart - rangeEnd) from src 1375 // Extract consecutive bits (defined by rangeStart - rangeEnd) from src
1099 // and place them into the least significant bits of dst. 1376 // and place them into the least significant bits of dst.
1100 inline void ExtractBitRange(Register dst, Register src, int rangeStart, 1377 inline void ExtractBitRange(Register dst, Register src, int rangeStart,
1101 int rangeEnd, RCBit rc = LeaveRC) { 1378 int rangeEnd) {
1102 DCHECK(rangeStart >= rangeEnd && rangeStart < kBitsPerPointer); 1379 DCHECK(rangeStart >= rangeEnd && rangeStart < kBitsPerPointer);
1103 int rotate = (rangeEnd == 0) ? 0 : kBitsPerPointer - rangeEnd; 1380
1104 int width = rangeStart - rangeEnd + 1; 1381 // Try to use RISBG if possible.
1105 if (rc == SetRC && rangeEnd == 0 && width <= 16) { 1382 if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
1106 andi(dst, src, Operand((1 << width) - 1)); 1383 int shiftAmount = (64 - rangeEnd) % 64; // Convert to shift left.
1384 int endBit = 63; // End is always LSB after shifting.
1385 int startBit = 63 - rangeStart + rangeEnd;
1386 risbg(dst, src, Operand(startBit), Operand(endBit), Operand(shiftAmount),
1387 true);
1107 } else { 1388 } else {
1108 #if V8_TARGET_ARCH_PPC64 1389 if (rangeEnd > 0) // Don't need to shift if rangeEnd is zero.
1109 rldicl(dst, src, rotate, kBitsPerPointer - width, rc); 1390 ShiftRightP(dst, src, Operand(rangeEnd));
1391 else if (!dst.is(src)) // If we didn't shift, we might need to copy
1392 LoadRR(dst, src);
1393 int width = rangeStart - rangeEnd + 1;
1394 #if V8_TARGET_ARCH_S390X
1395 uint64_t mask = (static_cast<uint64_t>(1) << width) - 1;
1396 nihf(dst, Operand(mask >> 32));
1397 nilf(dst, Operand(mask & 0xFFFFFFFF));
1398 ltgr(dst, dst);
1110 #else 1399 #else
1111 rlwinm(dst, src, rotate, kBitsPerPointer - width, kBitsPerPointer - 1, 1400 uint32_t mask = (1 << width) - 1;
1112 rc); 1401 AndP(dst, Operand(mask));
1113 #endif 1402 #endif
1114 } 1403 }
1115 } 1404 }
1116 1405
1117 inline void ExtractBit(Register dst, Register src, uint32_t bitNumber, 1406 inline void ExtractBit(Register dst, Register src, uint32_t bitNumber) {
1118 RCBit rc = LeaveRC) { 1407 ExtractBitRange(dst, src, bitNumber, bitNumber);
1119 ExtractBitRange(dst, src, bitNumber, bitNumber, rc);
1120 } 1408 }
1121 1409
1122 // Extract consecutive bits (defined by mask) from src and place them 1410 // Extract consecutive bits (defined by mask) from src and place them
1123 // into the least significant bits of dst. 1411 // into the least significant bits of dst.
1124 inline void ExtractBitMask(Register dst, Register src, uintptr_t mask, 1412 inline void ExtractBitMask(Register dst, Register src, uintptr_t mask,
1125 RCBit rc = LeaveRC) { 1413 RCBit rc = LeaveRC) {
1126 int start = kBitsPerPointer - 1; 1414 int start = kBitsPerPointer - 1;
1127 int end; 1415 int end;
1128 uintptr_t bit = (1L << start); 1416 uintptr_t bit = (1L << start);
1129 1417
1130 while (bit && (mask & bit) == 0) { 1418 while (bit && (mask & bit) == 0) {
1131 start--; 1419 start--;
1132 bit >>= 1; 1420 bit >>= 1;
1133 } 1421 }
1134 end = start; 1422 end = start;
1135 bit >>= 1; 1423 bit >>= 1;
1136 1424
1137 while (bit && (mask & bit)) { 1425 while (bit && (mask & bit)) {
1138 end--; 1426 end--;
1139 bit >>= 1; 1427 bit >>= 1;
1140 } 1428 }
1141 1429
1142 // 1-bits in mask must be contiguous 1430 // 1-bits in mask must be contiguous
1143 DCHECK(bit == 0 || (mask & ((bit << 1) - 1)) == 0); 1431 DCHECK(bit == 0 || (mask & ((bit << 1) - 1)) == 0);
1144 1432
1145 ExtractBitRange(dst, src, start, end, rc); 1433 ExtractBitRange(dst, src, start, end);
1146 } 1434 }
1147 1435
1148 // Test single bit in value. 1436 // Test single bit in value.
1149 inline void TestBit(Register value, int bitNumber, Register scratch = r0) { 1437 inline void TestBit(Register value, int bitNumber, Register scratch = r0) {
1150 ExtractBitRange(scratch, value, bitNumber, bitNumber, SetRC); 1438 ExtractBitRange(scratch, value, bitNumber, bitNumber);
1151 } 1439 }
1152 1440
1153 // Test consecutive bit range in value. Range is defined by 1441 // Test consecutive bit range in value. Range is defined by
1154 // rangeStart - rangeEnd. 1442 // rangeStart - rangeEnd.
1155 inline void TestBitRange(Register value, int rangeStart, int rangeEnd, 1443 inline void TestBitRange(Register value, int rangeStart, int rangeEnd,
1156 Register scratch = r0) { 1444 Register scratch = r0) {
1157 ExtractBitRange(scratch, value, rangeStart, rangeEnd, SetRC); 1445 ExtractBitRange(scratch, value, rangeStart, rangeEnd);
1158 } 1446 }
1159 1447
1160 // Test consecutive bit range in value. Range is defined by mask. 1448 // Test consecutive bit range in value. Range is defined by mask.
1161 inline void TestBitMask(Register value, uintptr_t mask, 1449 inline void TestBitMask(Register value, uintptr_t mask,
1162 Register scratch = r0) { 1450 Register scratch = r0) {
1163 ExtractBitMask(scratch, value, mask, SetRC); 1451 ExtractBitMask(scratch, value, mask, SetRC);
1164 } 1452 }
1165 1453
1166
1167 // --------------------------------------------------------------------------- 1454 // ---------------------------------------------------------------------------
1168 // Smi utilities 1455 // Smi utilities
1169 1456
1170 // Shift left by kSmiShift 1457 // Shift left by kSmiShift
1171 void SmiTag(Register reg, RCBit rc = LeaveRC) { SmiTag(reg, reg, rc); } 1458 void SmiTag(Register reg) { SmiTag(reg, reg); }
1172 void SmiTag(Register dst, Register src, RCBit rc = LeaveRC) { 1459 void SmiTag(Register dst, Register src) {
1173 ShiftLeftImm(dst, src, Operand(kSmiShift), rc); 1460 ShiftLeftP(dst, src, Operand(kSmiShift));
1174 } 1461 }
1175 1462
1176 #if !V8_TARGET_ARCH_PPC64 1463 #if !V8_TARGET_ARCH_S390X
1177 // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow(). 1464 // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
1178 void SmiTagCheckOverflow(Register reg, Register overflow); 1465 void SmiTagCheckOverflow(Register reg, Register overflow);
1179 void SmiTagCheckOverflow(Register dst, Register src, Register overflow); 1466 void SmiTagCheckOverflow(Register dst, Register src, Register overflow);
1180 1467
1181 inline void JumpIfNotSmiCandidate(Register value, Register scratch, 1468 inline void JumpIfNotSmiCandidate(Register value, Register scratch,
1182 Label* not_smi_label) { 1469 Label* not_smi_label) {
1183 // High bits must be identical to fit into an Smi 1470 // High bits must be identical to fit into an Smi
1184 STATIC_ASSERT(kSmiShift == 1); 1471 STATIC_ASSERT(kSmiShift == 1);
1185 addis(scratch, value, Operand(0x40000000u >> 16)); 1472 AddP(scratch, value, Operand(0x40000000u));
1186 cmpi(scratch, Operand::Zero()); 1473 CmpP(scratch, Operand::Zero());
1187 blt(not_smi_label); 1474 blt(not_smi_label);
1188 } 1475 }
1189 #endif 1476 #endif
1190 inline void TestUnsignedSmiCandidate(Register value, Register scratch) { 1477 inline void TestUnsignedSmiCandidate(Register value, Register scratch) {
1191 // The test is different for unsigned int values. Since we need 1478 // The test is different for unsigned int values. Since we need
1192 // the value to be in the range of a positive smi, we can't 1479 // the value to be in the range of a positive smi, we can't
1193 // handle any of the high bits being set in the value. 1480 // handle any of the high bits being set in the value.
1194 TestBitRange(value, kBitsPerPointer - 1, kBitsPerPointer - 1 - kSmiShift, 1481 TestBitRange(value, kBitsPerPointer - 1, kBitsPerPointer - 1 - kSmiShift,
1195 scratch); 1482 scratch);
1196 } 1483 }
1197 inline void JumpIfNotUnsignedSmiCandidate(Register value, Register scratch, 1484 inline void JumpIfNotUnsignedSmiCandidate(Register value, Register scratch,
1198 Label* not_smi_label) { 1485 Label* not_smi_label) {
1199 TestUnsignedSmiCandidate(value, scratch); 1486 TestUnsignedSmiCandidate(value, scratch);
1200 bne(not_smi_label, cr0); 1487 bne(not_smi_label /*, cr0*/);
1201 } 1488 }
1202 1489
1203 void SmiUntag(Register reg, RCBit rc = LeaveRC) { SmiUntag(reg, reg, rc); } 1490 void SmiUntag(Register reg) { SmiUntag(reg, reg); }
1204 1491
1205 void SmiUntag(Register dst, Register src, RCBit rc = LeaveRC) { 1492 void SmiUntag(Register dst, Register src) {
1206 ShiftRightArithImm(dst, src, kSmiShift, rc); 1493 ShiftRightArithP(dst, src, Operand(kSmiShift));
1207 } 1494 }
1208 1495
1209 void SmiToPtrArrayOffset(Register dst, Register src) { 1496 void SmiToPtrArrayOffset(Register dst, Register src) {
1210 #if V8_TARGET_ARCH_PPC64 1497 #if V8_TARGET_ARCH_S390X
1211 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2); 1498 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2);
1212 ShiftRightArithImm(dst, src, kSmiShift - kPointerSizeLog2); 1499 ShiftRightArithP(dst, src, Operand(kSmiShift - kPointerSizeLog2));
1213 #else 1500 #else
1214 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2); 1501 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2);
1215 ShiftLeftImm(dst, src, Operand(kPointerSizeLog2 - kSmiShift)); 1502 ShiftLeftP(dst, src, Operand(kPointerSizeLog2 - kSmiShift));
1216 #endif 1503 #endif
1217 } 1504 }
1218 1505
1219 void SmiToByteArrayOffset(Register dst, Register src) { SmiUntag(dst, src); } 1506 void SmiToByteArrayOffset(Register dst, Register src) { SmiUntag(dst, src); }
1220 1507
1221 void SmiToShortArrayOffset(Register dst, Register src) { 1508 void SmiToShortArrayOffset(Register dst, Register src) {
1222 #if V8_TARGET_ARCH_PPC64 1509 #if V8_TARGET_ARCH_S390X
1223 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 1); 1510 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 1);
1224 ShiftRightArithImm(dst, src, kSmiShift - 1); 1511 ShiftRightArithP(dst, src, Operand(kSmiShift - 1));
1225 #else 1512 #else
1226 STATIC_ASSERT(kSmiTag == 0 && kSmiShift == 1); 1513 STATIC_ASSERT(kSmiTag == 0 && kSmiShift == 1);
1227 if (!dst.is(src)) { 1514 if (!dst.is(src)) {
1228 mr(dst, src); 1515 LoadRR(dst, src);
1229 } 1516 }
1230 #endif 1517 #endif
1231 } 1518 }
1232 1519
1233 void SmiToIntArrayOffset(Register dst, Register src) { 1520 void SmiToIntArrayOffset(Register dst, Register src) {
1234 #if V8_TARGET_ARCH_PPC64 1521 #if V8_TARGET_ARCH_S390X
1235 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 2); 1522 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 2);
1236 ShiftRightArithImm(dst, src, kSmiShift - 2); 1523 ShiftRightArithP(dst, src, Operand(kSmiShift - 2));
1237 #else 1524 #else
1238 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < 2); 1525 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < 2);
1239 ShiftLeftImm(dst, src, Operand(2 - kSmiShift)); 1526 ShiftLeftP(dst, src, Operand(2 - kSmiShift));
1240 #endif 1527 #endif
1241 } 1528 }
1242 1529
1243 #define SmiToFloatArrayOffset SmiToIntArrayOffset 1530 #define SmiToFloatArrayOffset SmiToIntArrayOffset
1244 1531
1245 void SmiToDoubleArrayOffset(Register dst, Register src) { 1532 void SmiToDoubleArrayOffset(Register dst, Register src) {
1246 #if V8_TARGET_ARCH_PPC64 1533 #if V8_TARGET_ARCH_S390X
1247 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kDoubleSizeLog2); 1534 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kDoubleSizeLog2);
1248 ShiftRightArithImm(dst, src, kSmiShift - kDoubleSizeLog2); 1535 ShiftRightArithP(dst, src, Operand(kSmiShift - kDoubleSizeLog2));
1249 #else 1536 #else
1250 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kDoubleSizeLog2); 1537 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kDoubleSizeLog2);
1251 ShiftLeftImm(dst, src, Operand(kDoubleSizeLog2 - kSmiShift)); 1538 ShiftLeftP(dst, src, Operand(kDoubleSizeLog2 - kSmiShift));
1252 #endif 1539 #endif
1253 } 1540 }
1254 1541
1255 void SmiToArrayOffset(Register dst, Register src, int elementSizeLog2) { 1542 void SmiToArrayOffset(Register dst, Register src, int elementSizeLog2) {
1256 if (kSmiShift < elementSizeLog2) { 1543 if (kSmiShift < elementSizeLog2) {
1257 ShiftLeftImm(dst, src, Operand(elementSizeLog2 - kSmiShift)); 1544 ShiftLeftP(dst, src, Operand(elementSizeLog2 - kSmiShift));
1258 } else if (kSmiShift > elementSizeLog2) { 1545 } else if (kSmiShift > elementSizeLog2) {
1259 ShiftRightArithImm(dst, src, kSmiShift - elementSizeLog2); 1546 ShiftRightArithP(dst, src, Operand(kSmiShift - elementSizeLog2));
1260 } else if (!dst.is(src)) { 1547 } else if (!dst.is(src)) {
1261 mr(dst, src); 1548 LoadRR(dst, src);
1262 } 1549 }
1263 } 1550 }
1264 1551
1265 void IndexToArrayOffset(Register dst, Register src, int elementSizeLog2, 1552 void IndexToArrayOffset(Register dst, Register src, int elementSizeLog2,
1266 bool isSmi) { 1553 bool isSmi) {
1267 if (isSmi) { 1554 if (isSmi) {
1268 SmiToArrayOffset(dst, src, elementSizeLog2); 1555 SmiToArrayOffset(dst, src, elementSizeLog2);
1269 } else { 1556 } else {
1270 ShiftLeftImm(dst, src, Operand(elementSizeLog2)); 1557 ShiftLeftP(dst, src, Operand(elementSizeLog2));
1271 } 1558 }
1272 } 1559 }
1273 1560
1274 // Untag the source value into destination and jump if source is a smi. 1561 // Untag the source value into destination and jump if source is a smi.
1275 // Souce and destination can be the same register. 1562 // Souce and destination can be the same register.
1276 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case); 1563 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1277 1564
1278 // Untag the source value into destination and jump if source is not a smi. 1565 // Untag the source value into destination and jump if source is not a smi.
1279 // Souce and destination can be the same register. 1566 // Souce and destination can be the same register.
1280 void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case); 1567 void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
1281 1568
1282 inline void TestIfSmi(Register value, Register scratch) { 1569 inline void TestIfSmi(Register value) { tmll(value, Operand(1)); }
1283 TestBitRange(value, kSmiTagSize - 1, 0, scratch);
1284 }
1285 1570
1286 inline void TestIfPositiveSmi(Register value, Register scratch) { 1571 inline void TestIfPositiveSmi(Register value, Register scratch) {
1287 #if V8_TARGET_ARCH_PPC64 1572 STATIC_ASSERT((kSmiTagMask | kSmiSignMask) ==
1288 rldicl(scratch, value, 1, kBitsPerPointer - (1 + kSmiTagSize), SetRC); 1573 (intptr_t)(1UL << (kBitsPerPointer - 1) | 1));
1289 #else 1574 mov(scratch, Operand(kIntptrSignBit | kSmiTagMask));
1290 rlwinm(scratch, value, 1, kBitsPerPointer - (1 + kSmiTagSize), 1575 AndP(scratch, value);
1291 kBitsPerPointer - 1, SetRC);
1292 #endif
1293 } 1576 }
1294 1577
1295 // Jump the register contains a smi. 1578 // Jump the register contains a smi.
1296 inline void JumpIfSmi(Register value, Label* smi_label) { 1579 inline void JumpIfSmi(Register value, Label* smi_label) {
1297 TestIfSmi(value, r0); 1580 TestIfSmi(value);
1298 beq(smi_label, cr0); // branch if SMI 1581 beq(smi_label /*, cr0*/); // branch if SMI
1299 } 1582 }
1300 // Jump if either of the registers contain a non-smi. 1583 // Jump if either of the registers contain a non-smi.
1301 inline void JumpIfNotSmi(Register value, Label* not_smi_label) { 1584 inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
1302 TestIfSmi(value, r0); 1585 TestIfSmi(value);
1303 bne(not_smi_label, cr0); 1586 bne(not_smi_label /*, cr0*/);
1304 } 1587 }
1305 // Jump if either of the registers contain a non-smi. 1588 // Jump if either of the registers contain a non-smi.
1306 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi); 1589 void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
1307 // Jump if either of the registers contain a smi. 1590 // Jump if either of the registers contain a smi.
1308 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi); 1591 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
1309 1592
1310 // Abort execution if argument is a smi, enabled via --debug-code. 1593 // Abort execution if argument is a smi, enabled via --debug-code.
1311 void AssertNotSmi(Register object); 1594 void AssertNotSmi(Register object);
1312 void AssertSmi(Register object); 1595 void AssertSmi(Register object);
1313 1596
1314 1597 #if V8_TARGET_ARCH_S390X
1315 #if V8_TARGET_ARCH_PPC64 1598 inline void TestIfInt32(Register value, Register scratch) {
1316 inline void TestIfInt32(Register value, Register scratch,
1317 CRegister cr = cr7) {
1318 // High bits must be identical to fit into an 32-bit integer 1599 // High bits must be identical to fit into an 32-bit integer
1319 extsw(scratch, value); 1600 lgfr(scratch, value);
1320 cmp(scratch, value, cr); 1601 CmpP(scratch, value);
1321 } 1602 }
1322 #else 1603 #else
1323 inline void TestIfInt32(Register hi_word, Register lo_word, Register scratch, 1604 inline void TestIfInt32(Register hi_word, Register lo_word,
1324 CRegister cr = cr7) { 1605 Register scratch) {
1325 // High bits must be identical to fit into an 32-bit integer 1606 // High bits must be identical to fit into an 32-bit integer
1326 srawi(scratch, lo_word, 31); 1607 ShiftRightArith(scratch, lo_word, Operand(31));
1327 cmp(scratch, hi_word, cr); 1608 CmpP(scratch, hi_word);
1328 } 1609 }
1329 #endif 1610 #endif
1330 1611
1331 #if V8_TARGET_ARCH_PPC64 1612 #if V8_TARGET_ARCH_S390X
1332 // Ensure it is permissable to read/write int value directly from 1613 // Ensure it is permissable to read/write int value directly from
1333 // upper half of the smi. 1614 // upper half of the smi.
1334 STATIC_ASSERT(kSmiTag == 0); 1615 STATIC_ASSERT(kSmiTag == 0);
1335 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); 1616 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
1336 #endif 1617 #endif
1337 #if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN 1618 #if V8_TARGET_LITTLE_ENDIAN
1338 #define SmiWordOffset(offset) (offset + kPointerSize / 2) 1619 #define SmiWordOffset(offset) (offset + kPointerSize / 2)
1339 #else 1620 #else
1340 #define SmiWordOffset(offset) offset 1621 #define SmiWordOffset(offset) offset
1341 #endif 1622 #endif
1342 1623
1343 // Abort execution if argument is not a string, enabled via --debug-code. 1624 // Abort execution if argument is not a string, enabled via --debug-code.
1344 void AssertString(Register object); 1625 void AssertString(Register object);
1345 1626
1346 // Abort execution if argument is not a name, enabled via --debug-code. 1627 // Abort execution if argument is not a name, enabled via --debug-code.
1347 void AssertName(Register object); 1628 void AssertName(Register object);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 Label* failure); 1680 Label* failure);
1400 1681
1401 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name); 1682 void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name);
1402 1683
1403 void EmitSeqStringSetCharCheck(Register string, Register index, 1684 void EmitSeqStringSetCharCheck(Register string, Register index,
1404 Register value, uint32_t encoding_mask); 1685 Register value, uint32_t encoding_mask);
1405 1686
1406 // --------------------------------------------------------------------------- 1687 // ---------------------------------------------------------------------------
1407 // Patching helpers. 1688 // Patching helpers.
1408 1689
1409 // Decode offset from constant pool load instruction(s).
1410 // Caller must place the instruction word at <location> in <result>.
1411 void DecodeConstantPoolOffset(Register result, Register location);
1412
1413 void ClampUint8(Register output_reg, Register input_reg); 1690 void ClampUint8(Register output_reg, Register input_reg);
1414 1691
1415 // Saturate a value into 8-bit unsigned integer 1692 // Saturate a value into 8-bit unsigned integer
1416 // if input_value < 0, output_value is 0 1693 // if input_value < 0, output_value is 0
1417 // if input_value > 255, output_value is 255 1694 // if input_value > 255, output_value is 255
1418 // otherwise output_value is the (int)input_value (round to nearest) 1695 // otherwise output_value is the (int)input_value (round to nearest)
1419 void ClampDoubleToUint8(Register result_reg, DoubleRegister input_reg, 1696 void ClampDoubleToUint8(Register result_reg, DoubleRegister input_reg,
1420 DoubleRegister temp_double_reg); 1697 DoubleRegister temp_double_reg);
1421 1698
1422
1423 void LoadInstanceDescriptors(Register map, Register descriptors); 1699 void LoadInstanceDescriptors(Register map, Register descriptors);
1424 void EnumLength(Register dst, Register map); 1700 void EnumLength(Register dst, Register map);
1425 void NumberOfOwnDescriptors(Register dst, Register map); 1701 void NumberOfOwnDescriptors(Register dst, Register map);
1426 void LoadAccessor(Register dst, Register holder, int accessor_index, 1702 void LoadAccessor(Register dst, Register holder, int accessor_index,
1427 AccessorComponent accessor); 1703 AccessorComponent accessor);
1428 1704
1429 template <typename Field> 1705 template <typename Field>
1430 void DecodeField(Register dst, Register src, RCBit rc = LeaveRC) { 1706 void DecodeField(Register dst, Register src) {
1431 ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift, 1707 ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift);
1432 rc);
1433 } 1708 }
1434 1709
1435 template <typename Field> 1710 template <typename Field>
1436 void DecodeField(Register reg, RCBit rc = LeaveRC) { 1711 void DecodeField(Register reg) {
1437 DecodeField<Field>(reg, reg, rc); 1712 DecodeField<Field>(reg, reg);
1438 } 1713 }
1439 1714
1440 template <typename Field> 1715 template <typename Field>
1441 void DecodeFieldToSmi(Register dst, Register src) { 1716 void DecodeFieldToSmi(Register dst, Register src) {
1442 #if V8_TARGET_ARCH_PPC64 1717 // TODO(joransiu): Optimize into single instruction
1443 DecodeField<Field>(dst, src); 1718 DecodeField<Field>(dst, src);
1444 SmiTag(dst); 1719 SmiTag(dst);
1445 #else
1446 // 32-bit can do this in one instruction:
1447 int start = Field::kSize + kSmiShift - 1;
1448 int end = kSmiShift;
1449 int rotate = kSmiShift - Field::kShift;
1450 if (rotate < 0) {
1451 rotate += kBitsPerPointer;
1452 }
1453 rlwinm(dst, src, rotate, kBitsPerPointer - start - 1,
1454 kBitsPerPointer - end - 1);
1455 #endif
1456 } 1720 }
1457 1721
1458 template <typename Field> 1722 template <typename Field>
1459 void DecodeFieldToSmi(Register reg) { 1723 void DecodeFieldToSmi(Register reg) {
1460 DecodeFieldToSmi<Field>(reg, reg); 1724 DecodeFieldToSmi<Field>(reg, reg);
1461 } 1725 }
1462 1726
1463 // Load the type feedback vector from a JavaScript frame. 1727 // Load the type feedback vector from a JavaScript frame.
1464 void EmitLoadTypeFeedbackVector(Register vector); 1728 void EmitLoadTypeFeedbackVector(Register vector);
1465 1729
1466 // Activation support. 1730 // Activation support.
1467 void EnterFrame(StackFrame::Type type, 1731 void EnterFrame(StackFrame::Type type,
1468 bool load_constant_pool_pointer_reg = false); 1732 bool load_constant_pool_pointer_reg = false);
1469 // Returns the pc offset at which the frame ends. 1733 // Returns the pc offset at which the frame ends.
1470 int LeaveFrame(StackFrame::Type type, int stack_adjustment = 0); 1734 int LeaveFrame(StackFrame::Type type, int stack_adjustment = 0);
1471 1735
1472 // Expects object in r3 and returns map with validated enum cache 1736 // Expects object in r2 and returns map with validated enum cache
1473 // in r3. Assumes that any other register can be used as a scratch. 1737 // in r2. Assumes that any other register can be used as a scratch.
1474 void CheckEnumCache(Label* call_runtime); 1738 void CheckEnumCache(Label* call_runtime);
1475 1739
1476 // AllocationMemento support. Arrays may have an associated 1740 // AllocationMemento support. Arrays may have an associated
1477 // AllocationMemento object that can be checked for in order to pretransition 1741 // AllocationMemento object that can be checked for in order to pretransition
1478 // to another type. 1742 // to another type.
1479 // On entry, receiver_reg should point to the array object. 1743 // On entry, receiver_reg should point to the array object.
1480 // scratch_reg gets clobbered. 1744 // scratch_reg gets clobbered.
1481 // If allocation info is present, condition flags are set to eq. 1745 // If allocation info is present, condition flags are set to eq.
1482 void TestJSArrayForAllocationMemento(Register receiver_reg, 1746 void TestJSArrayForAllocationMemento(Register receiver_reg,
1483 Register scratch_reg, 1747 Register scratch_reg,
1484 Label* no_memento_found); 1748 Label* no_memento_found);
1485 1749
1486 void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, 1750 void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
1487 Register scratch_reg, 1751 Register scratch_reg,
1488 Label* memento_found) { 1752 Label* memento_found) {
1489 Label no_memento_found; 1753 Label no_memento_found;
1490 TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, 1754 TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
1491 &no_memento_found); 1755 &no_memento_found);
1492 beq(memento_found); 1756 beq(memento_found);
1493 bind(&no_memento_found); 1757 bind(&no_memento_found);
1494 } 1758 }
1495 1759
1496 // Jumps to found label if a prototype map has dictionary elements. 1760 // Jumps to found label if a prototype map has dictionary elements.
1497 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 1761 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
1498 Register scratch1, Label* found); 1762 Register scratch1, Label* found);
1499 1763
1500 // Loads the constant pool pointer (kConstantPoolRegister).
1501 void LoadConstantPoolPointerRegisterFromCodeTargetAddress(
1502 Register code_target_address);
1503 void LoadConstantPoolPointerRegister();
1504 void LoadConstantPoolPointerRegister(Register base, int code_entry_delta = 0);
1505
1506 void AbortConstantPoolBuilding() {
1507 #ifdef DEBUG
1508 // Avoid DCHECK(!is_linked()) failure in ~Label()
1509 bind(ConstantPoolPosition());
1510 #endif
1511 }
1512
1513 private: 1764 private:
1514 static const int kSmiShift = kSmiTagSize + kSmiShiftSize; 1765 static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
1515 1766
1516 void CallCFunctionHelper(Register function, int num_reg_arguments, 1767 void CallCFunctionHelper(Register function, int num_reg_arguments,
1517 int num_double_arguments); 1768 int num_double_arguments);
1518 1769
1519 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al, 1770 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al,
1520 CRegister cr = cr7); 1771 CRegister cr = cr7);
1521 1772
1522 // Helper functions for generating invokes. 1773 // Helper functions for generating invokes.
(...skipping 28 matching lines...) Expand all
1551 bool generating_stub_; 1802 bool generating_stub_;
1552 bool has_frame_; 1803 bool has_frame_;
1553 // This handle will be patched with the code object on installation. 1804 // This handle will be patched with the code object on installation.
1554 Handle<Object> code_object_; 1805 Handle<Object> code_object_;
1555 1806
1556 // Needs access to SafepointRegisterStackIndex for compiled frame 1807 // Needs access to SafepointRegisterStackIndex for compiled frame
1557 // traversal. 1808 // traversal.
1558 friend class StandardFrame; 1809 friend class StandardFrame;
1559 }; 1810 };
1560 1811
1561
1562 // The code patcher is used to patch (typically) small parts of code e.g. for 1812 // The code patcher is used to patch (typically) small parts of code e.g. for
1563 // debugging and other types of instrumentation. When using the code patcher 1813 // debugging and other types of instrumentation. When using the code patcher
1564 // the exact number of bytes specified must be emitted. It is not legal to emit 1814 // the exact number of bytes specified must be emitted. It is not legal to emit
1565 // relocation information. If any of these constraints are violated it causes 1815 // relocation information. If any of these constraints are violated it causes
1566 // an assertion to fail. 1816 // an assertion to fail.
1567 class CodePatcher { 1817 class CodePatcher {
1568 public: 1818 public:
1569 enum FlushICache { FLUSH, DONT_FLUSH }; 1819 enum FlushICache { FLUSH, DONT_FLUSH };
1570 1820
1571 CodePatcher(Isolate* isolate, byte* address, int instructions, 1821 CodePatcher(Isolate* isolate, byte* address, int instructions,
1572 FlushICache flush_cache = FLUSH); 1822 FlushICache flush_cache = FLUSH);
1573 ~CodePatcher(); 1823 ~CodePatcher();
1574 1824
1575 // Macro assembler to emit code. 1825 // Macro assembler to emit code.
1576 MacroAssembler* masm() { return &masm_; } 1826 MacroAssembler* masm() { return &masm_; }
1577 1827
1578 // Emit an instruction directly.
1579 void Emit(Instr instr);
1580
1581 // Emit the condition part of an instruction leaving the rest of the current
1582 // instruction unchanged.
1583 void EmitCondition(Condition cond);
1584
1585 private: 1828 private:
1586 byte* address_; // The address of the code being patched. 1829 byte* address_; // The address of the code being patched.
1587 int size_; // Number of bytes of the expected patch size. 1830 int size_; // Number of bytes of the expected patch size.
1588 MacroAssembler masm_; // Macro assembler used to generate the code. 1831 MacroAssembler masm_; // Macro assembler used to generate the code.
1589 FlushICache flush_cache_; // Whether to flush the I cache after patching. 1832 FlushICache flush_cache_; // Whether to flush the I cache after patching.
1590 }; 1833 };
1591 1834
1592
1593 // ----------------------------------------------------------------------------- 1835 // -----------------------------------------------------------------------------
1594 // Static helper functions. 1836 // Static helper functions.
1595 1837
1596 inline MemOperand ContextMemOperand(Register context, int index = 0) { 1838 inline MemOperand ContextMemOperand(Register context, int index = 0) {
1597 return MemOperand(context, Context::SlotOffset(index)); 1839 return MemOperand(context, Context::SlotOffset(index));
1598 } 1840 }
1599 1841
1600
1601 inline MemOperand NativeContextMemOperand() { 1842 inline MemOperand NativeContextMemOperand() {
1602 return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX); 1843 return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX);
1603 } 1844 }
1604 1845
1605
1606 #ifdef GENERATED_CODE_COVERAGE 1846 #ifdef GENERATED_CODE_COVERAGE
1607 #define CODE_COVERAGE_STRINGIFY(x) #x 1847 #define CODE_COVERAGE_STRINGIFY(x) #x
1608 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 1848 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1609 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 1849 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1610 #define ACCESS_MASM(masm) \ 1850 #define ACCESS_MASM(masm) \
1611 masm->stop(__FILE_LINE__); \ 1851 masm->stop(__FILE_LINE__); \
1612 masm-> 1852 masm->
1613 #else 1853 #else
1614 #define ACCESS_MASM(masm) masm-> 1854 #define ACCESS_MASM(masm) masm->
1615 #endif 1855 #endif
1616 } // namespace internal 1856 } // namespace internal
1617 } // namespace v8 1857 } // namespace v8
1618 1858
1619 #endif // V8_PPC_MACRO_ASSEMBLER_PPC_H_ 1859 #endif // V8_S390_MACRO_ASSEMBLER_S390_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698