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

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

Issue 7888003: MIPS: pre-crankshaft updates to assembler and related files. (1/3) (Closed)
Patch Set: Created 9 years, 3 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
« no previous file with comments | « no previous file | src/mips/assembler-mips.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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 const Register ra = { 31 }; // ra: Return address pointer. 161 const Register ra = { 31 }; // ra: Return address pointer.
162 162
163 163
164 int ToNumber(Register reg); 164 int ToNumber(Register reg);
165 165
166 Register ToRegister(int num); 166 Register ToRegister(int num);
167 167
168 // Coprocessor register. 168 // Coprocessor register.
169 struct FPURegister { 169 struct FPURegister {
170 static const int kNumRegisters = v8::internal::kNumFPURegisters; 170 static const int kNumRegisters = v8::internal::kNumFPURegisters;
171 // f0 has been excluded from allocation. This is following ia32 171
172 // where xmm0 is excluded. 172 // TODO(plind): Warning, inconsistent numbering here. kNumFPURegisters refers
173 static const int kNumAllocatableRegisters = 15; 173 // to number of 32-bit FPU regs, but kNumAllocatableRegisters refers to
174 // number of Double regs (64-bit regs, or FPU-reg-pairs).
175
176 // A few double registers are reserved: one as a scratch register and one to
177 // hold 0.0.
178 // f28: 0.0
179 // f30: scratch register.
180 static const int kNumReservedRegisters = 2;
181 static const int kNumAllocatableRegisters = kNumRegisters / 2 -
182 kNumReservedRegisters;
183
174 184
175 static int ToAllocationIndex(FPURegister reg) { 185 static int ToAllocationIndex(FPURegister reg) {
176 ASSERT(reg.code() != 0);
177 ASSERT(reg.code() % 2 == 0); 186 ASSERT(reg.code() % 2 == 0);
178 return (reg.code() / 2) - 1; 187 ASSERT(reg.code() / 2 < kNumAllocatableRegisters);
188 ASSERT(reg.is_valid());
189 return (reg.code() / 2);
179 } 190 }
180 191
181 static FPURegister FromAllocationIndex(int index) { 192 static FPURegister FromAllocationIndex(int index) {
182 ASSERT(index >= 0 && index < kNumAllocatableRegisters); 193 ASSERT(index >= 0 && index < kNumAllocatableRegisters);
183 return from_code((index + 1) * 2); 194 return from_code(index * 2);
184 } 195 }
185 196
186 static const char* AllocationIndexToString(int index) { 197 static const char* AllocationIndexToString(int index) {
187 ASSERT(index >= 0 && index < kNumAllocatableRegisters); 198 ASSERT(index >= 0 && index < kNumAllocatableRegisters);
188 const char* const names[] = { 199 const char* const names[] = {
200 "f0",
189 "f2", 201 "f2",
190 "f4", 202 "f4",
191 "f6", 203 "f6",
192 "f8", 204 "f8",
193 "f10", 205 "f10",
194 "f12", 206 "f12",
195 "f14", 207 "f14",
196 "f16", 208 "f16",
197 "f18", 209 "f18",
198 "f20", 210 "f20",
199 "f22", 211 "f22",
200 "f24", 212 "f24",
201 "f26", 213 "f26"
202 "f28",
203 "f30"
204 }; 214 };
205 return names[index]; 215 return names[index];
206 } 216 }
207 217
208 static FPURegister from_code(int code) { 218 static FPURegister from_code(int code) {
209 FPURegister r = { code }; 219 FPURegister r = { code };
210 return r; 220 return r;
211 } 221 }
212 222
213 bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegisters ; } 223 bool is_valid() const { return 0 <= code_ && code_ < kNumFPURegisters ; }
214 bool is(FPURegister creg) const { return code_ == creg.code_; } 224 bool is(FPURegister creg) const { return code_ == creg.code_; }
225 FPURegister low() const {
226 // Find low reg of a Double-reg pair, which is the reg itself.
227 ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
228 FPURegister reg;
229 reg.code_ = code_;
230 ASSERT(reg.is_valid());
231 return reg;
232 }
233 FPURegister high() const {
234 // Find high reg of a Doubel-reg pair, which is reg + 1.
235 ASSERT(code_ % 2 == 0); // Specified Double reg must be even.
236 FPURegister reg;
237 reg.code_ = code_ + 1;
238 ASSERT(reg.is_valid());
239 return reg;
240 }
241
215 int code() const { 242 int code() const {
216 ASSERT(is_valid()); 243 ASSERT(is_valid());
217 return code_; 244 return code_;
218 } 245 }
219 int bit() const { 246 int bit() const {
220 ASSERT(is_valid()); 247 ASSERT(is_valid());
221 return 1 << code_; 248 return 1 << code_;
222 } 249 }
223 void setcode(int f) { 250 void setcode(int f) {
224 code_ = f; 251 code_ = f;
225 ASSERT(is_valid()); 252 ASSERT(is_valid());
226 } 253 }
227 // Unfortunately we can't make this private in a struct. 254 // Unfortunately we can't make this private in a struct.
228 int code_; 255 int code_;
229 }; 256 };
230 257
258 // V8 now supports the O32 ABI, and the FPU Registers are organized as 32
259 // 32-bit registers, f0 through f31. When used as 'double' they are used
260 // in pairs, starting with the even numbered register. So a double operation
261 // on f0 really uses f0 and f1.
262 // (Modern mips hardware also supports 32 64-bit registers, via setting
263 // (priviledged) Status Register FR bit to 1. This is used by the N32 ABI,
264 // but it is not in common use. Someday we will want to support this in v8.)
265
266 // For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers.
231 typedef FPURegister DoubleRegister; 267 typedef FPURegister DoubleRegister;
268 typedef FPURegister FloatRegister;
232 269
233 const FPURegister no_creg = { -1 }; 270 const FPURegister no_freg = { -1 };
234 271
235 const FPURegister f0 = { 0 }; // Return value in hard float mode. 272 const FPURegister f0 = { 0 }; // Return value in hard float mode.
236 const FPURegister f1 = { 1 }; 273 const FPURegister f1 = { 1 };
237 const FPURegister f2 = { 2 }; 274 const FPURegister f2 = { 2 };
238 const FPURegister f3 = { 3 }; 275 const FPURegister f3 = { 3 };
239 const FPURegister f4 = { 4 }; 276 const FPURegister f4 = { 4 };
240 const FPURegister f5 = { 5 }; 277 const FPURegister f5 = { 5 };
241 const FPURegister f6 = { 6 }; 278 const FPURegister f6 = { 6 };
242 const FPURegister f7 = { 7 }; 279 const FPURegister f7 = { 7 };
243 const FPURegister f8 = { 8 }; 280 const FPURegister f8 = { 8 };
(...skipping 14 matching lines...) Expand all
258 const FPURegister f23 = { 23 }; 295 const FPURegister f23 = { 23 };
259 const FPURegister f24 = { 24 }; 296 const FPURegister f24 = { 24 };
260 const FPURegister f25 = { 25 }; 297 const FPURegister f25 = { 25 };
261 const FPURegister f26 = { 26 }; 298 const FPURegister f26 = { 26 };
262 const FPURegister f27 = { 27 }; 299 const FPURegister f27 = { 27 };
263 const FPURegister f28 = { 28 }; 300 const FPURegister f28 = { 28 };
264 const FPURegister f29 = { 29 }; 301 const FPURegister f29 = { 29 };
265 const FPURegister f30 = { 30 }; 302 const FPURegister f30 = { 30 };
266 const FPURegister f31 = { 31 }; 303 const FPURegister f31 = { 31 };
267 304
305 const FPURegister kDoubleRegZero = f28;
306
268 // FPU (coprocessor 1) control registers. 307 // FPU (coprocessor 1) control registers.
269 // Currently only FCSR (#31) is implemented. 308 // Currently only FCSR (#31) is implemented.
270 struct FPUControlRegister { 309 struct FPUControlRegister {
271 bool is_valid() const { return code_ == kFCSRRegister; } 310 bool is_valid() const { return code_ == kFCSRRegister; }
272 bool is(FPUControlRegister creg) const { return code_ == creg.code_; } 311 bool is(FPUControlRegister creg) const { return code_ == creg.code_; }
273 int code() const { 312 int code() const {
274 ASSERT(is_valid()); 313 ASSERT(is_valid());
275 return code_; 314 return code_;
276 } 315 }
277 int bit() const { 316 int bit() const {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 }; 363 };
325 364
326 365
327 // On MIPS we have only one adressing mode with base_reg + offset. 366 // On MIPS we have only one adressing mode with base_reg + offset.
328 // Class MemOperand represents a memory operand in load and store instructions. 367 // Class MemOperand represents a memory operand in load and store instructions.
329 class MemOperand : public Operand { 368 class MemOperand : public Operand {
330 public: 369 public:
331 explicit MemOperand(Register rn, int32_t offset = 0); 370 explicit MemOperand(Register rn, int32_t offset = 0);
332 int32_t offset() const { return offset_; } 371 int32_t offset() const { return offset_; }
333 372
373 bool OffsetIsInt16Encodable() const {
374 return is_int16(offset_);
375 }
376
334 private: 377 private:
335 int32_t offset_; 378 int32_t offset_;
336 379
337 friend class Assembler; 380 friend class Assembler;
338 }; 381 };
339 382
340 383
341 // CpuFeatures keeps track of which features are supported by the target CPU. 384 // CpuFeatures keeps track of which features are supported by the target CPU.
342 // Supported features must be enabled by a Scope before use. 385 // Supported features must be enabled by a Scope before use.
343 class CpuFeatures : public AllStatic { 386 class CpuFeatures : public AllStatic {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 uint32_t jump_address(Label* L); 540 uint32_t jump_address(Label* L);
498 541
499 // Puts a labels target address at the given position. 542 // Puts a labels target address at the given position.
500 // The high 8 bits are set to zero. 543 // The high 8 bits are set to zero.
501 void label_at_put(Label* L, int at_offset); 544 void label_at_put(Label* L, int at_offset);
502 545
503 // Read/Modify the code target address in the branch/call instruction at pc. 546 // Read/Modify the code target address in the branch/call instruction at pc.
504 static Address target_address_at(Address pc); 547 static Address target_address_at(Address pc);
505 static void set_target_address_at(Address pc, Address target); 548 static void set_target_address_at(Address pc, Address target);
506 549
550 static void JumpLabelToJumpRegister(Address pc);
551
507 // This sets the branch destination (which gets loaded at the call address). 552 // This sets the branch destination (which gets loaded at the call address).
508 // This is for calls and branches within generated code. 553 // This is for calls and branches within generated code.
509 inline static void set_target_at(Address instruction_payload, 554 inline static void set_target_at(Address instruction_payload,
510 Address target) { 555 Address target) {
511 set_target_address_at(instruction_payload, target); 556 set_target_address_at(instruction_payload, target);
512 } 557 }
513 558
514 // This sets the branch destination. 559 // This sets the branch destination.
515 // This is for calls and branches to runtime code. 560 // This is for calls and branches to runtime code.
516 inline static void set_external_target_at(Address instruction_payload, 561 inline static void set_external_target_at(Address instruction_payload,
(...skipping 10 matching lines...) Expand all
527 // Here we are patching the address in the LUI/ORI instruction pair. 572 // Here we are patching the address in the LUI/ORI instruction pair.
528 // These values are used in the serialization process and must be zero for 573 // These values are used in the serialization process and must be zero for
529 // MIPS platform, as Code, Embedded Object or External-reference pointers 574 // MIPS platform, as Code, Embedded Object or External-reference pointers
530 // are split across two consecutive instructions and don't exist separately 575 // are split across two consecutive instructions and don't exist separately
531 // in the code, so the serializer should not step forwards in memory after 576 // in the code, so the serializer should not step forwards in memory after
532 // a target is resolved and written. 577 // a target is resolved and written.
533 static const int kCallTargetSize = 0 * kInstrSize; 578 static const int kCallTargetSize = 0 * kInstrSize;
534 static const int kExternalTargetSize = 0 * kInstrSize; 579 static const int kExternalTargetSize = 0 * kInstrSize;
535 580
536 // Number of consecutive instructions used to store 32bit constant. 581 // Number of consecutive instructions used to store 32bit constant.
537 // Used in RelocInfo::target_address_address() function to tell serializer 582 // Before jump-optimizations, this constant was used in
538 // address of the instruction that follows LUI/ORI instruction pair. 583 // RelocInfo::target_address_address() function to tell serializer address of
539 static const int kInstructionsFor32BitConstant = 2; 584 // the instruction that follows LUI/ORI instruction pair. Now, with new jump
585 // optimization, where jump-through-register instruction that usually
586 // follows LUI/ORI pair is substituted with J/JAL, this constant equals
587 // to 3 instructions (LUI+ORI+J/JAL/JR/JALR).
588 static const int kInstructionsFor32BitConstant = 3;
540 589
541 // Distance between the instruction referring to the address of the call 590 // Distance between the instruction referring to the address of the call
542 // target and the return address. 591 // target and the return address.
543 static const int kCallTargetAddressOffset = 4 * kInstrSize; 592 static const int kCallTargetAddressOffset = 4 * kInstrSize;
544 593
545 // Distance between start of patched return sequence and the emitted address 594 // Distance between start of patched return sequence and the emitted address
546 // to jump to. 595 // to jump to.
547 static const int kPatchReturnSequenceAddressOffset = 0; 596 static const int kPatchReturnSequenceAddressOffset = 0;
548 597
549 // Distance between start of patched debug break slot and the emitted address 598 // Distance between start of patched debug break slot and the emitted address
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 } 665 }
617 666
618 // Never use the int16_t b(l)cond version with a branch offset 667 // Never use the int16_t b(l)cond version with a branch offset
619 // instead of using the Label* version. 668 // instead of using the Label* version.
620 669
621 // Jump targets must be in the current 256 MB-aligned region. ie 28 bits. 670 // Jump targets must be in the current 256 MB-aligned region. ie 28 bits.
622 void j(int32_t target); 671 void j(int32_t target);
623 void jal(int32_t target); 672 void jal(int32_t target);
624 void jalr(Register rs, Register rd = ra); 673 void jalr(Register rs, Register rd = ra);
625 void jr(Register target); 674 void jr(Register target);
675 void j_or_jr(int32_t target, Register rs);
676 void jal_or_jalr(int32_t target, Register rs);
626 677
627 678
628 //-------Data-processing-instructions--------- 679 //-------Data-processing-instructions---------
629 680
630 // Arithmetic. 681 // Arithmetic.
631 void addu(Register rd, Register rs, Register rt); 682 void addu(Register rd, Register rs, Register rt);
632 void subu(Register rd, Register rs, Register rt); 683 void subu(Register rd, Register rs, Register rt);
633 void mult(Register rs, Register rt); 684 void mult(Register rs, Register rt);
634 void multu(Register rs, Register rt); 685 void multu(Register rs, Register rt);
635 void div(Register rs, Register rt); 686 void div(Register rs, Register rt);
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 // Check if an instruction is a branch of some kind. 936 // Check if an instruction is a branch of some kind.
886 static bool IsBranch(Instr instr); 937 static bool IsBranch(Instr instr);
887 static bool IsBeq(Instr instr); 938 static bool IsBeq(Instr instr);
888 static bool IsBne(Instr instr); 939 static bool IsBne(Instr instr);
889 940
890 static bool IsJump(Instr instr); 941 static bool IsJump(Instr instr);
891 static bool IsJ(Instr instr); 942 static bool IsJ(Instr instr);
892 static bool IsLui(Instr instr); 943 static bool IsLui(Instr instr);
893 static bool IsOri(Instr instr); 944 static bool IsOri(Instr instr);
894 945
946 static bool IsJal(Instr instr);
947 static bool IsJr(Instr instr);
948 static bool IsJalr(Instr instr);
949
895 static bool IsNop(Instr instr, unsigned int type); 950 static bool IsNop(Instr instr, unsigned int type);
896 static bool IsPop(Instr instr); 951 static bool IsPop(Instr instr);
897 static bool IsPush(Instr instr); 952 static bool IsPush(Instr instr);
898 static bool IsLwRegFpOffset(Instr instr); 953 static bool IsLwRegFpOffset(Instr instr);
899 static bool IsSwRegFpOffset(Instr instr); 954 static bool IsSwRegFpOffset(Instr instr);
900 static bool IsLwRegFpNegOffset(Instr instr); 955 static bool IsLwRegFpNegOffset(Instr instr);
901 static bool IsSwRegFpNegOffset(Instr instr); 956 static bool IsSwRegFpNegOffset(Instr instr);
902 957
903 static Register GetRtReg(Instr instr); 958 static Register GetRtReg(Instr instr);
904 static Register GetRsReg(Instr instr); 959 static Register GetRsReg(Instr instr);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 } 1024 }
970 1025
971 bool is_trampoline_pool_blocked() const { 1026 bool is_trampoline_pool_blocked() const {
972 return trampoline_pool_blocked_nesting_ > 0; 1027 return trampoline_pool_blocked_nesting_ > 0;
973 } 1028 }
974 1029
975 bool has_exception() const { 1030 bool has_exception() const {
976 return internal_trampoline_exception_; 1031 return internal_trampoline_exception_;
977 } 1032 }
978 1033
1034 void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
1035
979 bool is_trampoline_emitted() const { 1036 bool is_trampoline_emitted() const {
980 return trampoline_emitted_; 1037 return trampoline_emitted_;
981 } 1038 }
982 1039
983 // Temporarily block automatic assembly buffer growth. 1040 // Temporarily block automatic assembly buffer growth.
984 void StartBlockGrowBuffer() { 1041 void StartBlockGrowBuffer() {
985 ASSERT(!block_buffer_growth_); 1042 ASSERT(!block_buffer_growth_);
986 block_buffer_growth_ = true; 1043 block_buffer_growth_ = true;
987 } 1044 }
988 1045
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 class EnsureSpace BASE_EMBEDDED { 1254 class EnsureSpace BASE_EMBEDDED {
1198 public: 1255 public:
1199 explicit EnsureSpace(Assembler* assembler) { 1256 explicit EnsureSpace(Assembler* assembler) {
1200 assembler->CheckBuffer(); 1257 assembler->CheckBuffer();
1201 } 1258 }
1202 }; 1259 };
1203 1260
1204 } } // namespace v8::internal 1261 } } // namespace v8::internal
1205 1262
1206 #endif // V8_ARM_ASSEMBLER_MIPS_H_ 1263 #endif // V8_ARM_ASSEMBLER_MIPS_H_
OLDNEW
« no previous file with comments | « no previous file | src/mips/assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698