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

Side by Side Diff: src/mips64/assembler-mips64.h

Issue 371923006: Add mips64 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/mips64/OWNERS ('k') | src/mips64/assembler-mips64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 19 matching lines...) Expand all
30 30
31 // The original source code covered by the above license above has been 31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc. 32 // modified significantly by Google Inc.
33 // Copyright 2012 the V8 project authors. All rights reserved. 33 // Copyright 2012 the V8 project authors. All rights reserved.
34 34
35 35
36 #ifndef V8_MIPS_ASSEMBLER_MIPS_H_ 36 #ifndef V8_MIPS_ASSEMBLER_MIPS_H_
37 #define V8_MIPS_ASSEMBLER_MIPS_H_ 37 #define V8_MIPS_ASSEMBLER_MIPS_H_
38 38
39 #include <stdio.h> 39 #include <stdio.h>
40
41 #include "src/assembler.h" 40 #include "src/assembler.h"
42 #include "src/mips/constants-mips.h" 41 #include "src/mips64/constants-mips64.h"
43 #include "src/serialize.h" 42 #include "src/serialize.h"
44 43
45 namespace v8 { 44 namespace v8 {
46 namespace internal { 45 namespace internal {
47 46
48 // CPU Registers. 47 // CPU Registers.
49 // 48 //
50 // 1) We would prefer to use an enum, but enum values are assignment- 49 // 1) We would prefer to use an enum, but enum values are assignment-
51 // compatible with int, which has caused code-generation bugs. 50 // compatible with int, which has caused code-generation bugs.
52 // 51 //
(...skipping 14 matching lines...) Expand all
67 // and best performance in optimized code. 66 // and best performance in optimized code.
68 67
69 68
70 // ----------------------------------------------------------------------------- 69 // -----------------------------------------------------------------------------
71 // Implementation of Register and FPURegister. 70 // Implementation of Register and FPURegister.
72 71
73 // Core register. 72 // Core register.
74 struct Register { 73 struct Register {
75 static const int kNumRegisters = v8::internal::kNumRegisters; 74 static const int kNumRegisters = v8::internal::kNumRegisters;
76 static const int kMaxNumAllocatableRegisters = 14; // v0 through t6 and cp. 75 static const int kMaxNumAllocatableRegisters = 14; // v0 through t6 and cp.
77 static const int kSizeInBytes = 4; 76 static const int kSizeInBytes = 8;
78 static const int kCpRegister = 23; // cp (s7) is the 23rd register. 77 static const int kCpRegister = 23; // cp (s7) is the 23rd register.
79 78
80 #if defined(V8_TARGET_LITTLE_ENDIAN)
81 static const int kMantissaOffset = 0;
82 static const int kExponentOffset = 4;
83 #elif defined(V8_TARGET_BIG_ENDIAN)
84 static const int kMantissaOffset = 4;
85 static const int kExponentOffset = 0;
86 #else
87 #error Unknown endianness
88 #endif
89
90 inline static int NumAllocatableRegisters(); 79 inline static int NumAllocatableRegisters();
91 80
92 static int ToAllocationIndex(Register reg) { 81 static int ToAllocationIndex(Register reg) {
93 ASSERT((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) || 82 ASSERT((reg.code() - 2) < (kMaxNumAllocatableRegisters - 1) ||
94 reg.is(from_code(kCpRegister))); 83 reg.is(from_code(kCpRegister)));
95 return reg.is(from_code(kCpRegister)) ? 84 return reg.is(from_code(kCpRegister)) ?
96 kMaxNumAllocatableRegisters - 1 : // Return last index for 'cp'. 85 kMaxNumAllocatableRegisters - 1 : // Return last index for 'cp'.
97 reg.code() - 2; // zero_reg and 'at' are skipped. 86 reg.code() - 2; // zero_reg and 'at' are skipped.
98 } 87 }
99 88
100 static Register FromAllocationIndex(int index) { 89 static Register FromAllocationIndex(int index) {
101 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 90 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
102 return index == kMaxNumAllocatableRegisters - 1 ? 91 return index == kMaxNumAllocatableRegisters - 1 ?
103 from_code(kCpRegister) : // Last index is always the 'cp' register. 92 from_code(kCpRegister) : // Last index is always the 'cp' register.
104 from_code(index + 2); // zero_reg and 'at' are skipped. 93 from_code(index + 2); // zero_reg and 'at' are skipped.
105 } 94 }
106 95
107 static const char* AllocationIndexToString(int index) { 96 static const char* AllocationIndexToString(int index) {
108 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); 97 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters);
109 const char* const names[] = { 98 const char* const names[] = {
110 "v0", 99 "v0",
111 "v1", 100 "v1",
112 "a0", 101 "a0",
113 "a1", 102 "a1",
114 "a2", 103 "a2",
115 "a3", 104 "a3",
105 "a4",
106 "a5",
107 "a6",
108 "a7",
116 "t0", 109 "t0",
117 "t1", 110 "t1",
118 "t2", 111 "t2",
119 "t3",
120 "t4",
121 "t5",
122 "t6",
123 "s7", 112 "s7",
124 }; 113 };
125 return names[index]; 114 return names[index];
126 } 115 }
127 116
128 static Register from_code(int code) { 117 static Register from_code(int code) {
129 Register r = { code }; 118 Register r = { code };
130 return r; 119 return r;
131 } 120 }
132 121
(...skipping 22 matching lines...) Expand all
155 // at: Reserved for synthetic instructions. 144 // at: Reserved for synthetic instructions.
156 REGISTER(at, 1); 145 REGISTER(at, 1);
157 // v0, v1: Used when returning multiple values from subroutines. 146 // v0, v1: Used when returning multiple values from subroutines.
158 REGISTER(v0, 2); 147 REGISTER(v0, 2);
159 REGISTER(v1, 3); 148 REGISTER(v1, 3);
160 // a0 - a4: Used to pass non-FP parameters. 149 // a0 - a4: Used to pass non-FP parameters.
161 REGISTER(a0, 4); 150 REGISTER(a0, 4);
162 REGISTER(a1, 5); 151 REGISTER(a1, 5);
163 REGISTER(a2, 6); 152 REGISTER(a2, 6);
164 REGISTER(a3, 7); 153 REGISTER(a3, 7);
165 // t0 - t9: Can be used without reservation, act as temporary registers and are 154 // a4 - a7 t0 - t3: Can be used without reservation, act as temporary registers
166 // allowed to be destroyed by subroutines. 155 // and are allowed to be destroyed by subroutines.
167 REGISTER(t0, 8); 156 REGISTER(a4, 8);
168 REGISTER(t1, 9); 157 REGISTER(a5, 9);
169 REGISTER(t2, 10); 158 REGISTER(a6, 10);
170 REGISTER(t3, 11); 159 REGISTER(a7, 11);
171 REGISTER(t4, 12); 160 REGISTER(t0, 12);
172 REGISTER(t5, 13); 161 REGISTER(t1, 13);
173 REGISTER(t6, 14); 162 REGISTER(t2, 14);
174 REGISTER(t7, 15); 163 REGISTER(t3, 15);
175 // s0 - s7: Subroutine register variables. Subroutines that write to these 164 // s0 - s7: Subroutine register variables. Subroutines that write to these
176 // registers must restore their values before exiting so that the caller can 165 // registers must restore their values before exiting so that the caller can
177 // expect the values to be preserved. 166 // expect the values to be preserved.
178 REGISTER(s0, 16); 167 REGISTER(s0, 16);
179 REGISTER(s1, 17); 168 REGISTER(s1, 17);
180 REGISTER(s2, 18); 169 REGISTER(s2, 18);
181 REGISTER(s3, 19); 170 REGISTER(s3, 19);
182 REGISTER(s4, 20); 171 REGISTER(s4, 20);
183 REGISTER(s5, 21); 172 REGISTER(s5, 21);
184 REGISTER(s6, 22); 173 REGISTER(s6, 22);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 220 }
232 221
233 static FPURegister from_code(int code) { 222 static FPURegister from_code(int code) {
234 FPURegister r = { code }; 223 FPURegister r = { code };
235 return r; 224 return r;
236 } 225 }
237 226
238 bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; } 227 bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters ; }
239 bool is(FPURegister creg) const { return code_ == creg.code_; } 228 bool is(FPURegister creg) const { return code_ == creg.code_; }
240 FPURegister low() const { 229 FPURegister low() const {
230 // TODO(plind): Create ASSERT for FR=0 mode. This usage suspect for FR=1.
241 // Find low reg of a Double-reg pair, which is the reg itself. 231 // Find low reg of a Double-reg pair, which is the reg itself.
242 ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 232 ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
243 FPURegister reg; 233 FPURegister reg;
244 reg.code_ = code_; 234 reg.code_ = code_;
245 ASSERT(reg.is_valid()); 235 ASSERT(reg.is_valid());
246 return reg; 236 return reg;
247 } 237 }
248 FPURegister high() const { 238 FPURegister high() const {
239 // TODO(plind): Create ASSERT for FR=0 mode. This usage illegal in FR=1.
249 // Find high reg of a Doubel-reg pair, which is reg + 1. 240 // Find high reg of a Doubel-reg pair, which is reg + 1.
250 ASSERT(code_ % 2 == 0); // Specified Double reg must be even. 241 ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
251 FPURegister reg; 242 FPURegister reg;
252 reg.code_ = code_ + 1; 243 reg.code_ = code_ + 1;
253 ASSERT(reg.is_valid()); 244 ASSERT(reg.is_valid());
254 return reg; 245 return reg;
255 } 246 }
256 247
257 int code() const { 248 int code() const {
258 ASSERT(is_valid()); 249 ASSERT(is_valid());
259 return code_; 250 return code_;
260 } 251 }
261 int bit() const { 252 int bit() const {
262 ASSERT(is_valid()); 253 ASSERT(is_valid());
263 return 1 << code_; 254 return 1 << code_;
264 } 255 }
265 void setcode(int f) { 256 void setcode(int f) {
266 code_ = f; 257 code_ = f;
267 ASSERT(is_valid()); 258 ASSERT(is_valid());
268 } 259 }
269 // Unfortunately we can't make this private in a struct. 260 // Unfortunately we can't make this private in a struct.
270 int code_; 261 int code_;
271 }; 262 };
272 263
273 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32 264 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32
274 // 32-bit registers, f0 through f31. When used as 'double' they are used 265 // 32-bit registers, f0 through f31. When used as 'double' they are used
275 // in pairs, starting with the even numbered register. So a double operation 266 // in pairs, starting with the even numbered register. So a double operation
276 // on f0 really uses f0 and f1. 267 // on f0 really uses f0 and f1.
277 // (Modern mips hardware also supports 32 64-bit registers, via setting 268 // (Modern mips hardware also supports 32 64-bit registers, via setting
278 // (priviledged) Status Register FR bit to 1. This is used by the N32 ABI, 269 // (privileged) Status Register FR bit to 1. This is used by the N32 ABI,
279 // but it is not in common use. Someday we will want to support this in v8.) 270 // but it is not in common use. Someday we will want to support this in v8.)
280 271
281 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. 272 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
282 typedef FPURegister DoubleRegister; 273 typedef FPURegister DoubleRegister;
283 typedef FPURegister FloatRegister; 274 typedef FPURegister FloatRegister;
284 275
285 const FPURegister no_freg = { -1 }; 276 const FPURegister no_freg = { -1 };
286 277
287 const FPURegister f0 = { 0 }; // Return value in hard float mode. 278 const FPURegister f0 = { 0 }; // Return value in hard float mode.
288 const FPURegister f1 = { 1 }; 279 const FPURegister f1 = { 1 };
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 // Unfortunately we can't make this private in a struct. 340 // Unfortunately we can't make this private in a struct.
350 int code_; 341 int code_;
351 }; 342 };
352 343
353 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; 344 const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
354 const FPUControlRegister FCSR = { kFCSRRegister }; 345 const FPUControlRegister FCSR = { kFCSRRegister };
355 346
356 347
357 // ----------------------------------------------------------------------------- 348 // -----------------------------------------------------------------------------
358 // Machine instruction Operands. 349 // Machine instruction Operands.
359 350 const int kSmiShift = kSmiTagSize + kSmiShiftSize;
351 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
360 // Class Operand represents a shifter operand in data processing instructions. 352 // Class Operand represents a shifter operand in data processing instructions.
361 class Operand BASE_EMBEDDED { 353 class Operand BASE_EMBEDDED {
362 public: 354 public:
363 // Immediate. 355 // Immediate.
364 INLINE(explicit Operand(int32_t immediate, 356 INLINE(explicit Operand(int64_t immediate,
365 RelocInfo::Mode rmode = RelocInfo::NONE32)); 357 RelocInfo::Mode rmode = RelocInfo::NONE64));
366 INLINE(explicit Operand(const ExternalReference& f)); 358 INLINE(explicit Operand(const ExternalReference& f));
367 INLINE(explicit Operand(const char* s)); 359 INLINE(explicit Operand(const char* s));
368 INLINE(explicit Operand(Object** opp)); 360 INLINE(explicit Operand(Object** opp));
369 INLINE(explicit Operand(Context** cpp)); 361 INLINE(explicit Operand(Context** cpp));
370 explicit Operand(Handle<Object> handle); 362 explicit Operand(Handle<Object> handle);
371 INLINE(explicit Operand(Smi* value)); 363 INLINE(explicit Operand(Smi* value));
372 364
373 // Register. 365 // Register.
374 INLINE(explicit Operand(Register rm)); 366 INLINE(explicit Operand(Register rm));
375 367
376 // Return true if this is a register operand. 368 // Return true if this is a register operand.
377 INLINE(bool is_reg() const); 369 INLINE(bool is_reg() const);
378 370
379 inline int32_t immediate() const { 371 inline int64_t immediate() const {
380 ASSERT(!is_reg()); 372 ASSERT(!is_reg());
381 return imm32_; 373 return imm64_;
382 } 374 }
383 375
384 Register rm() const { return rm_; } 376 Register rm() const { return rm_; }
385 377
386 private: 378 private:
387 Register rm_; 379 Register rm_;
388 int32_t imm32_; // Valid if rm_ == no_reg. 380 int64_t imm64_; // Valid if rm_ == no_reg.
389 RelocInfo::Mode rmode_; 381 RelocInfo::Mode rmode_;
390 382
391 friend class Assembler; 383 friend class Assembler;
392 friend class MacroAssembler; 384 friend class MacroAssembler;
393 }; 385 };
394 386
395 387
396 // On MIPS we have only one adressing mode with base_reg + offset. 388 // On MIPS we have only one adressing mode with base_reg + offset.
397 // Class MemOperand represents a memory operand in load and store instructions. 389 // Class MemOperand represents a memory operand in load and store instructions.
398 class MemOperand : public Operand { 390 class MemOperand : public Operand {
399 public: 391 public:
400 // Immediate value attached to offset. 392 // Immediate value attached to offset.
401 enum OffsetAddend { 393 enum OffsetAddend {
402 offset_minus_one = -1, 394 offset_minus_one = -1,
403 offset_zero = 0 395 offset_zero = 0
404 }; 396 };
405 397
406 explicit MemOperand(Register rn, int32_t offset = 0); 398 explicit MemOperand(Register rn, int64_t offset = 0);
407 explicit MemOperand(Register rn, int32_t unit, int32_t multiplier, 399 explicit MemOperand(Register rn, int64_t unit, int64_t multiplier,
408 OffsetAddend offset_addend = offset_zero); 400 OffsetAddend offset_addend = offset_zero);
409 int32_t offset() const { return offset_; } 401 int32_t offset() const { return offset_; }
410 402
411 bool OffsetIsInt16Encodable() const { 403 bool OffsetIsInt16Encodable() const {
412 return is_int16(offset_); 404 return is_int16(offset_);
413 } 405 }
414 406
415 private: 407 private:
416 int32_t offset_; 408 int32_t offset_;
417 409
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 455
464 // Returns the branch offset to the given label from the current code 456 // Returns the branch offset to the given label from the current code
465 // position. Links the label to the current position if it is still unbound. 457 // position. Links the label to the current position if it is still unbound.
466 // Manages the jump elimination optimization if the second parameter is true. 458 // Manages the jump elimination optimization if the second parameter is true.
467 int32_t branch_offset(Label* L, bool jump_elimination_allowed); 459 int32_t branch_offset(Label* L, bool jump_elimination_allowed);
468 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) { 460 int32_t shifted_branch_offset(Label* L, bool jump_elimination_allowed) {
469 int32_t o = branch_offset(L, jump_elimination_allowed); 461 int32_t o = branch_offset(L, jump_elimination_allowed);
470 ASSERT((o & 3) == 0); // Assert the offset is aligned. 462 ASSERT((o & 3) == 0); // Assert the offset is aligned.
471 return o >> 2; 463 return o >> 2;
472 } 464 }
473 uint32_t jump_address(Label* L); 465 uint64_t jump_address(Label* L);
474 466
475 // Puts a labels target address at the given position. 467 // Puts a labels target address at the given position.
476 // The high 8 bits are set to zero. 468 // The high 8 bits are set to zero.
477 void label_at_put(Label* L, int at_offset); 469 void label_at_put(Label* L, int at_offset);
478 470
479 // Read/Modify the code target address in the branch/call instruction at pc. 471 // Read/Modify the code target address in the branch/call instruction at pc.
480 static Address target_address_at(Address pc); 472 static Address target_address_at(Address pc);
481 static void set_target_address_at(Address pc, 473 static void set_target_address_at(Address pc,
482 Address target, 474 Address target,
483 ICacheFlushMode icache_flush_mode = 475 ICacheFlushMode icache_flush_mode =
(...skipping 30 matching lines...) Expand all
514 static void JumpLabelToJumpRegister(Address pc); 506 static void JumpLabelToJumpRegister(Address pc);
515 507
516 static void QuietNaN(HeapObject* nan); 508 static void QuietNaN(HeapObject* nan);
517 509
518 // This sets the branch destination (which gets loaded at the call address). 510 // This sets the branch destination (which gets loaded at the call address).
519 // This is for calls and branches within generated code. The serializer 511 // This is for calls and branches within generated code. The serializer
520 // has already deserialized the lui/ori instructions etc. 512 // has already deserialized the lui/ori instructions etc.
521 inline static void deserialization_set_special_target_at( 513 inline static void deserialization_set_special_target_at(
522 Address instruction_payload, Code* code, Address target) { 514 Address instruction_payload, Code* code, Address target) {
523 set_target_address_at( 515 set_target_address_at(
524 instruction_payload - kInstructionsFor32BitConstant * kInstrSize, 516 instruction_payload - kInstructionsFor64BitConstant * kInstrSize,
525 code, 517 code,
526 target); 518 target);
527 } 519 }
528 520
529 // Size of an instruction. 521 // Size of an instruction.
530 static const int kInstrSize = sizeof(Instr); 522 static const int kInstrSize = sizeof(Instr);
531 523
532 // Difference between address of current opcode and target address offset. 524 // Difference between address of current opcode and target address offset.
533 static const int kBranchPCOffset = 4; 525 static const int kBranchPCOffset = 4;
534 526
535 // Here we are patching the address in the LUI/ORI instruction pair. 527 // Here we are patching the address in the LUI/ORI instruction pair.
536 // These values are used in the serialization process and must be zero for 528 // These values are used in the serialization process and must be zero for
537 // MIPS platform, as Code, Embedded Object or External-reference pointers 529 // MIPS platform, as Code, Embedded Object or External-reference pointers
538 // are split across two consecutive instructions and don't exist separately 530 // are split across two consecutive instructions and don't exist separately
539 // in the code, so the serializer should not step forwards in memory after 531 // in the code, so the serializer should not step forwards in memory after
540 // a target is resolved and written. 532 // a target is resolved and written.
541 static const int kSpecialTargetSize = 0; 533 static const int kSpecialTargetSize = 0;
542 534
543 // Number of consecutive instructions used to store 32bit constant. 535 // Number of consecutive instructions used to store 32bit/64bit constant.
544 // Before jump-optimizations, this constant was used in 536 // Before jump-optimizations, this constant was used in
545 // RelocInfo::target_address_address() function to tell serializer address of 537 // RelocInfo::target_address_address() function to tell serializer address of
546 // the instruction that follows LUI/ORI instruction pair. Now, with new jump 538 // the instruction that follows LUI/ORI instruction pair. Now, with new jump
547 // optimization, where jump-through-register instruction that usually 539 // optimization, where jump-through-register instruction that usually
548 // follows LUI/ORI pair is substituted with J/JAL, this constant equals 540 // follows LUI/ORI pair is substituted with J/JAL, this constant equals
549 // to 3 instructions (LUI+ORI+J/JAL/JR/JALR). 541 // to 3 instructions (LUI+ORI+J/JAL/JR/JALR).
550 static const int kInstructionsFor32BitConstant = 3; 542 static const int kInstructionsFor32BitConstant = 3;
543 static const int kInstructionsFor64BitConstant = 5;
551 544
552 // Distance between the instruction referring to the address of the call 545 // Distance between the instruction referring to the address of the call
553 // target and the return address. 546 // target and the return address.
554 static const int kCallTargetAddressOffset = 4 * kInstrSize; 547 static const int kCallTargetAddressOffset = 6 * kInstrSize;
555 548
556 // Distance between start of patched return sequence and the emitted address 549 // Distance between start of patched return sequence and the emitted address
557 // to jump to. 550 // to jump to.
558 static const int kPatchReturnSequenceAddressOffset = 0; 551 static const int kPatchReturnSequenceAddressOffset = 0;
559 552
560 // Distance between start of patched debug break slot and the emitted address 553 // Distance between start of patched debug break slot and the emitted address
561 // to jump to. 554 // to jump to.
562 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize; 555 static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
563 556
564 // Difference between address of current opcode and value read from pc 557 // Difference between address of current opcode and value read from pc
565 // register. 558 // register.
566 static const int kPcLoadDelta = 4; 559 static const int kPcLoadDelta = 4;
567 560
568 static const int kPatchDebugBreakSlotReturnOffset = 4 * kInstrSize; 561 static const int kPatchDebugBreakSlotReturnOffset = 6 * kInstrSize;
569 562
570 // Number of instructions used for the JS return sequence. The constant is 563 // Number of instructions used for the JS return sequence. The constant is
571 // used by the debugger to patch the JS return sequence. 564 // used by the debugger to patch the JS return sequence.
572 static const int kJSReturnSequenceInstructions = 7; 565 static const int kJSReturnSequenceInstructions = 7;
573 static const int kDebugBreakSlotInstructions = 4; 566 static const int kDebugBreakSlotInstructions = 6;
574 static const int kDebugBreakSlotLength = 567 static const int kDebugBreakSlotLength =
575 kDebugBreakSlotInstructions * kInstrSize; 568 kDebugBreakSlotInstructions * kInstrSize;
576 569
577 570
578 // --------------------------------------------------------------------------- 571 // ---------------------------------------------------------------------------
579 // Code generation. 572 // Code generation.
580 573
581 // Insert the smallest number of nop instructions 574 // Insert the smallest number of nop instructions
582 // possible to align the pc offset to a multiple 575 // possible to align the pc offset to a multiple
583 // of m. m must be a power of 2 (>= 4). 576 // of m. m must be a power of 2 (>= 4).
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 void bltzal(Register rs, int16_t offset); 624 void bltzal(Register rs, int16_t offset);
632 void bne(Register rs, Register rt, int16_t offset); 625 void bne(Register rs, Register rt, int16_t offset);
633 void bne(Register rs, Register rt, Label* L) { 626 void bne(Register rs, Register rt, Label* L) {
634 bne(rs, rt, branch_offset(L, false)>>2); 627 bne(rs, rt, branch_offset(L, false)>>2);
635 } 628 }
636 629
637 // Never use the int16_t b(l)cond version with a branch offset 630 // Never use the int16_t b(l)cond version with a branch offset
638 // instead of using the Label* version. 631 // instead of using the Label* version.
639 632
640 // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits. 633 // Jump targets must be in the current 256 MB-aligned region. i.e. 28 bits.
641 void j(int32_t target); 634 void j(int64_t target);
642 void jal(int32_t target); 635 void jal(int64_t target);
643 void jalr(Register rs, Register rd = ra); 636 void jalr(Register rs, Register rd = ra);
644 void jr(Register target); 637 void jr(Register target);
645 void j_or_jr(int32_t target, Register rs); 638 void j_or_jr(int64_t target, Register rs);
646 void jal_or_jalr(int32_t target, Register rs); 639 void jal_or_jalr(int64_t target, Register rs);
647 640
648 641
649 // -------Data-processing-instructions--------- 642 // -------Data-processing-instructions---------
650 643
651 // Arithmetic. 644 // Arithmetic.
652 void addu(Register rd, Register rs, Register rt); 645 void addu(Register rd, Register rs, Register rt);
653 void subu(Register rd, Register rs, Register rt); 646 void subu(Register rd, Register rs, Register rt);
654 void mult(Register rs, Register rt); 647 void mult(Register rs, Register rt);
655 void multu(Register rs, Register rt); 648 void multu(Register rs, Register rt);
656 void div(Register rs, Register rt); 649 void div(Register rs, Register rt);
657 void divu(Register rs, Register rt); 650 void divu(Register rs, Register rt);
658 void mul(Register rd, Register rs, Register rt); 651 void mul(Register rd, Register rs, Register rt);
652 void daddu(Register rd, Register rs, Register rt);
653 void dsubu(Register rd, Register rs, Register rt);
654 void dmult(Register rs, Register rt);
655 void dmultu(Register rs, Register rt);
656 void ddiv(Register rs, Register rt);
657 void ddivu(Register rs, Register rt);
659 658
660 void addiu(Register rd, Register rs, int32_t j); 659 void addiu(Register rd, Register rs, int32_t j);
660 void daddiu(Register rd, Register rs, int32_t j);
661 661
662 // Logical. 662 // Logical.
663 void and_(Register rd, Register rs, Register rt); 663 void and_(Register rd, Register rs, Register rt);
664 void or_(Register rd, Register rs, Register rt); 664 void or_(Register rd, Register rs, Register rt);
665 void xor_(Register rd, Register rs, Register rt); 665 void xor_(Register rd, Register rs, Register rt);
666 void nor(Register rd, Register rs, Register rt); 666 void nor(Register rd, Register rs, Register rt);
667 667
668 void andi(Register rd, Register rs, int32_t j); 668 void andi(Register rd, Register rs, int32_t j);
669 void ori(Register rd, Register rs, int32_t j); 669 void ori(Register rd, Register rs, int32_t j);
670 void xori(Register rd, Register rs, int32_t j); 670 void xori(Register rd, Register rs, int32_t j);
671 void lui(Register rd, int32_t j); 671 void lui(Register rd, int32_t j);
672 672
673 // Shifts. 673 // Shifts.
674 // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop 674 // Please note: sll(zero_reg, zero_reg, x) instructions are reserved as nop
675 // and may cause problems in normal code. coming_from_nop makes sure this 675 // and may cause problems in normal code. coming_from_nop makes sure this
676 // doesn't happen. 676 // doesn't happen.
677 void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false); 677 void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop = false);
678 void sllv(Register rd, Register rt, Register rs); 678 void sllv(Register rd, Register rt, Register rs);
679 void srl(Register rd, Register rt, uint16_t sa); 679 void srl(Register rd, Register rt, uint16_t sa);
680 void srlv(Register rd, Register rt, Register rs); 680 void srlv(Register rd, Register rt, Register rs);
681 void sra(Register rt, Register rd, uint16_t sa); 681 void sra(Register rt, Register rd, uint16_t sa);
682 void srav(Register rt, Register rd, Register rs); 682 void srav(Register rt, Register rd, Register rs);
683 void rotr(Register rd, Register rt, uint16_t sa); 683 void rotr(Register rd, Register rt, uint16_t sa);
684 void rotrv(Register rd, Register rt, Register rs); 684 void rotrv(Register rd, Register rt, Register rs);
685 void dsll(Register rd, Register rt, uint16_t sa);
686 void dsllv(Register rd, Register rt, Register rs);
687 void dsrl(Register rd, Register rt, uint16_t sa);
688 void dsrlv(Register rd, Register rt, Register rs);
689 void drotr(Register rd, Register rt, uint16_t sa);
690 void drotrv(Register rd, Register rt, Register rs);
691 void dsra(Register rt, Register rd, uint16_t sa);
692 void dsrav(Register rd, Register rt, Register rs);
693 void dsll32(Register rt, Register rd, uint16_t sa);
694 void dsrl32(Register rt, Register rd, uint16_t sa);
695 void dsra32(Register rt, Register rd, uint16_t sa);
685 696
686 697
687 // ------------Memory-instructions------------- 698 // ------------Memory-instructions-------------
688 699
689 void lb(Register rd, const MemOperand& rs); 700 void lb(Register rd, const MemOperand& rs);
690 void lbu(Register rd, const MemOperand& rs); 701 void lbu(Register rd, const MemOperand& rs);
691 void lh(Register rd, const MemOperand& rs); 702 void lh(Register rd, const MemOperand& rs);
692 void lhu(Register rd, const MemOperand& rs); 703 void lhu(Register rd, const MemOperand& rs);
693 void lw(Register rd, const MemOperand& rs); 704 void lw(Register rd, const MemOperand& rs);
705 void lwu(Register rd, const MemOperand& rs);
694 void lwl(Register rd, const MemOperand& rs); 706 void lwl(Register rd, const MemOperand& rs);
695 void lwr(Register rd, const MemOperand& rs); 707 void lwr(Register rd, const MemOperand& rs);
696 void sb(Register rd, const MemOperand& rs); 708 void sb(Register rd, const MemOperand& rs);
697 void sh(Register rd, const MemOperand& rs); 709 void sh(Register rd, const MemOperand& rs);
698 void sw(Register rd, const MemOperand& rs); 710 void sw(Register rd, const MemOperand& rs);
699 void swl(Register rd, const MemOperand& rs); 711 void swl(Register rd, const MemOperand& rs);
700 void swr(Register rd, const MemOperand& rs); 712 void swr(Register rd, const MemOperand& rs);
713 void ldl(Register rd, const MemOperand& rs);
714 void ldr(Register rd, const MemOperand& rs);
715 void sdl(Register rd, const MemOperand& rs);
716 void sdr(Register rd, const MemOperand& rs);
717 void ld(Register rd, const MemOperand& rs);
718 void sd(Register rd, const MemOperand& rs);
701 719
702 720
703 // ----------------Prefetch-------------------- 721 // ----------------Prefetch--------------------
704 722
705 void pref(int32_t hint, const MemOperand& rs); 723 void pref(int32_t hint, const MemOperand& rs);
706 724
707 725
708 // -------------Misc-instructions-------------- 726 // -------------Misc-instructions--------------
709 727
710 // Break / Trap instructions. 728 // Break / Trap instructions.
(...skipping 30 matching lines...) Expand all
741 // --------Coprocessor-instructions---------------- 759 // --------Coprocessor-instructions----------------
742 760
743 // Load, store, and move. 761 // Load, store, and move.
744 void lwc1(FPURegister fd, const MemOperand& src); 762 void lwc1(FPURegister fd, const MemOperand& src);
745 void ldc1(FPURegister fd, const MemOperand& src); 763 void ldc1(FPURegister fd, const MemOperand& src);
746 764
747 void swc1(FPURegister fs, const MemOperand& dst); 765 void swc1(FPURegister fs, const MemOperand& dst);
748 void sdc1(FPURegister fs, const MemOperand& dst); 766 void sdc1(FPURegister fs, const MemOperand& dst);
749 767
750 void mtc1(Register rt, FPURegister fs); 768 void mtc1(Register rt, FPURegister fs);
769 void mthc1(Register rt, FPURegister fs);
770 void dmtc1(Register rt, FPURegister fs);
771
751 void mfc1(Register rt, FPURegister fs); 772 void mfc1(Register rt, FPURegister fs);
773 void mfhc1(Register rt, FPURegister fs);
774 void dmfc1(Register rt, FPURegister fs);
752 775
753 void ctc1(Register rt, FPUControlRegister fs); 776 void ctc1(Register rt, FPUControlRegister fs);
754 void cfc1(Register rt, FPUControlRegister fs); 777 void cfc1(Register rt, FPUControlRegister fs);
755 778
756 // Arithmetic. 779 // Arithmetic.
757 void add_d(FPURegister fd, FPURegister fs, FPURegister ft); 780 void add_d(FPURegister fd, FPURegister fs, FPURegister ft);
758 void sub_d(FPURegister fd, FPURegister fs, FPURegister ft); 781 void sub_d(FPURegister fd, FPURegister fs, FPURegister ft);
759 void mul_d(FPURegister fd, FPURegister fs, FPURegister ft); 782 void mul_d(FPURegister fd, FPURegister fs, FPURegister ft);
760 void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft); 783 void madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft);
761 void div_d(FPURegister fd, FPURegister fs, FPURegister ft); 784 void div_d(FPURegister fd, FPURegister fs, FPURegister ft);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 993
971 // Generate the constant pool for the generated code. 994 // Generate the constant pool for the generated code.
972 void PopulateConstantPool(ConstantPoolArray* constant_pool); 995 void PopulateConstantPool(ConstantPoolArray* constant_pool);
973 996
974 protected: 997 protected:
975 // Relocation for a type-recording IC has the AST id added to it. This 998 // Relocation for a type-recording IC has the AST id added to it. This
976 // member variable is a way to pass the information from the call site to 999 // member variable is a way to pass the information from the call site to
977 // the relocation info. 1000 // the relocation info.
978 TypeFeedbackId recorded_ast_id_; 1001 TypeFeedbackId recorded_ast_id_;
979 1002
980 int32_t buffer_space() const { return reloc_info_writer.pos() - pc_; } 1003 int64_t buffer_space() const { return reloc_info_writer.pos() - pc_; }
981 1004
982 // Decode branch instruction at pos and return branch target pos. 1005 // Decode branch instruction at pos and return branch target pos.
983 int target_at(int32_t pos); 1006 int64_t target_at(int64_t pos);
984 1007
985 // Patch branch instruction at pos to branch to given branch target pos. 1008 // Patch branch instruction at pos to branch to given branch target pos.
986 void target_at_put(int32_t pos, int32_t target_pos); 1009 void target_at_put(int64_t pos, int64_t target_pos);
987 1010
988 // Say if we need to relocate with this mode. 1011 // Say if we need to relocate with this mode.
989 bool MustUseReg(RelocInfo::Mode rmode); 1012 bool MustUseReg(RelocInfo::Mode rmode);
990 1013
991 // Record reloc info for current pc_. 1014 // Record reloc info for current pc_.
992 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1015 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
993 1016
994 // Block the emission of the trampoline pool before pc_offset. 1017 // Block the emission of the trampoline pool before pc_offset.
995 void BlockTrampolinePoolBefore(int pc_offset) { 1018 void BlockTrampolinePoolBefore(int pc_offset) {
996 if (no_trampoline_pool_before_ < pc_offset) 1019 if (no_trampoline_pool_before_ < pc_offset)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1093 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1071 RelocInfoWriter reloc_info_writer; 1094 RelocInfoWriter reloc_info_writer;
1072 1095
1073 // The bound position, before this we cannot do instruction elimination. 1096 // The bound position, before this we cannot do instruction elimination.
1074 int last_bound_pos_; 1097 int last_bound_pos_;
1075 1098
1076 // Code emission. 1099 // Code emission.
1077 inline void CheckBuffer(); 1100 inline void CheckBuffer();
1078 void GrowBuffer(); 1101 void GrowBuffer();
1079 inline void emit(Instr x); 1102 inline void emit(Instr x);
1103 inline void emit(uint64_t x);
1080 inline void CheckTrampolinePoolQuick(); 1104 inline void CheckTrampolinePoolQuick();
1081 1105
1082 // Instruction generation. 1106 // Instruction generation.
1083 // We have 3 different kind of encoding layout on MIPS. 1107 // We have 3 different kind of encoding layout on MIPS.
1084 // However due to many different types of objects encoded in the same fields 1108 // However due to many different types of objects encoded in the same fields
1085 // we have quite a few aliases for each mode. 1109 // we have quite a few aliases for each mode.
1086 // Using the same structure to refer to Register and FPURegister would spare a 1110 // Using the same structure to refer to Register and FPURegister would spare a
1087 // few aliases, but mixing both does not look clean to me. 1111 // few aliases, but mixing both does not look clean to me.
1088 // Anyway we could surely implement this differently. 1112 // Anyway we could surely implement this differently.
1089 1113
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 }; 1230 };
1207 1231
1208 int32_t get_trampoline_entry(int32_t pos); 1232 int32_t get_trampoline_entry(int32_t pos);
1209 int unbound_labels_count_; 1233 int unbound_labels_count_;
1210 // If trampoline is emitted, generated code is becoming large. As this is 1234 // If trampoline is emitted, generated code is becoming large. As this is
1211 // already a slow case which can possibly break our code generation for the 1235 // already a slow case which can possibly break our code generation for the
1212 // extreme case, we use this information to trigger different mode of 1236 // extreme case, we use this information to trigger different mode of
1213 // branch instruction generation, where we use jump instructions rather 1237 // branch instruction generation, where we use jump instructions rather
1214 // than regular branch instructions. 1238 // than regular branch instructions.
1215 bool trampoline_emitted_; 1239 bool trampoline_emitted_;
1216 static const int kTrampolineSlotsSize = 4 * kInstrSize; 1240 static const int kTrampolineSlotsSize = 6 * kInstrSize;
1217 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; 1241 static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
1218 static const int kInvalidSlotPos = -1; 1242 static const int kInvalidSlotPos = -1;
1219 1243
1220 Trampoline trampoline_; 1244 Trampoline trampoline_;
1221 bool internal_trampoline_exception_; 1245 bool internal_trampoline_exception_;
1222 1246
1223 friend class RegExpMacroAssemblerMIPS; 1247 friend class RegExpMacroAssemblerMIPS;
1224 friend class RelocInfo; 1248 friend class RelocInfo;
1225 friend class CodePatcher; 1249 friend class CodePatcher;
1226 friend class BlockTrampolinePoolScope; 1250 friend class BlockTrampolinePoolScope;
1227 1251
1228 PositionsRecorder positions_recorder_; 1252 PositionsRecorder positions_recorder_;
1229 friend class PositionsRecorder; 1253 friend class PositionsRecorder;
1230 friend class EnsureSpace; 1254 friend class EnsureSpace;
1231 }; 1255 };
1232 1256
1233 1257
1234 class EnsureSpace BASE_EMBEDDED { 1258 class EnsureSpace BASE_EMBEDDED {
1235 public: 1259 public:
1236 explicit EnsureSpace(Assembler* assembler) { 1260 explicit EnsureSpace(Assembler* assembler) {
1237 assembler->CheckBuffer(); 1261 assembler->CheckBuffer();
1238 } 1262 }
1239 }; 1263 };
1240 1264
1241 } } // namespace v8::internal 1265 } } // namespace v8::internal
1242 1266
1243 #endif // V8_ARM_ASSEMBLER_MIPS_H_ 1267 #endif // V8_ARM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « src/mips64/OWNERS ('k') | src/mips64/assembler-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698