OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64_ASSEMBLER_ARM64_H_ | 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ |
6 #define V8_ARM64_ASSEMBLER_ARM64_H_ | 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <list> | 9 #include <list> |
10 #include <map> | 10 #include <map> |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 | 74 |
75 enum RegisterType { | 75 enum RegisterType { |
76 // The kInvalid value is used to detect uninitialized static instances, | 76 // The kInvalid value is used to detect uninitialized static instances, |
77 // which are always zero-initialized before any constructors are called. | 77 // which are always zero-initialized before any constructors are called. |
78 kInvalid = 0, | 78 kInvalid = 0, |
79 kRegister, | 79 kRegister, |
80 kFPRegister, | 80 kFPRegister, |
81 kNoRegister | 81 kNoRegister |
82 }; | 82 }; |
83 | 83 |
84 static CPURegister Create(unsigned code, unsigned size, RegisterType type) { | 84 static CPURegister Create(int code, int size, RegisterType type) { |
85 CPURegister r = {code, size, type}; | 85 CPURegister r = {code, size, type}; |
86 return r; | 86 return r; |
87 } | 87 } |
88 | 88 |
89 unsigned code() const; | 89 int code() const; |
90 RegisterType type() const; | 90 RegisterType type() const; |
91 RegList Bit() const; | 91 RegList Bit() const; |
92 unsigned SizeInBits() const; | 92 int SizeInBits() const; |
93 int SizeInBytes() const; | 93 int SizeInBytes() const; |
94 bool Is32Bits() const; | 94 bool Is32Bits() const; |
95 bool Is64Bits() const; | 95 bool Is64Bits() const; |
96 bool IsValid() const; | 96 bool IsValid() const; |
97 bool IsValidOrNone() const; | 97 bool IsValidOrNone() const; |
98 bool IsValidRegister() const; | 98 bool IsValidRegister() const; |
99 bool IsValidFPRegister() const; | 99 bool IsValidFPRegister() const; |
100 bool IsNone() const; | 100 bool IsNone() const; |
101 bool Is(const CPURegister& other) const; | 101 bool Is(const CPURegister& other) const; |
102 bool Aliases(const CPURegister& other) const; | 102 bool Aliases(const CPURegister& other) const; |
103 | 103 |
104 bool IsZero() const; | 104 bool IsZero() const; |
105 bool IsSP() const; | 105 bool IsSP() const; |
106 | 106 |
107 bool IsRegister() const; | 107 bool IsRegister() const; |
108 bool IsFPRegister() const; | 108 bool IsFPRegister() const; |
109 | 109 |
110 Register X() const; | 110 Register X() const; |
111 Register W() const; | 111 Register W() const; |
112 FPRegister D() const; | 112 FPRegister D() const; |
113 FPRegister S() const; | 113 FPRegister S() const; |
114 | 114 |
115 bool IsSameSizeAndType(const CPURegister& other) const; | 115 bool IsSameSizeAndType(const CPURegister& other) const; |
116 | 116 |
117 // V8 compatibility. | 117 // V8 compatibility. |
118 bool is(const CPURegister& other) const { return Is(other); } | 118 bool is(const CPURegister& other) const { return Is(other); } |
119 bool is_valid() const { return IsValid(); } | 119 bool is_valid() const { return IsValid(); } |
120 | 120 |
121 unsigned reg_code; | 121 int reg_code; |
122 unsigned reg_size; | 122 int reg_size; |
123 RegisterType reg_type; | 123 RegisterType reg_type; |
124 }; | 124 }; |
125 | 125 |
126 | 126 |
127 struct Register : public CPURegister { | 127 struct Register : public CPURegister { |
128 static Register Create(unsigned code, unsigned size) { | 128 static Register Create(int code, int size) { |
129 return Register(CPURegister::Create(code, size, CPURegister::kRegister)); | 129 return Register(CPURegister::Create(code, size, CPURegister::kRegister)); |
130 } | 130 } |
131 | 131 |
132 Register() { | 132 Register() { |
133 reg_code = 0; | 133 reg_code = 0; |
134 reg_size = 0; | 134 reg_size = 0; |
135 reg_type = CPURegister::kNoRegister; | 135 reg_type = CPURegister::kNoRegister; |
136 } | 136 } |
137 | 137 |
138 explicit Register(const CPURegister& r) { | 138 explicit Register(const CPURegister& r) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 193 |
194 struct FPRegister : public CPURegister { | 194 struct FPRegister : public CPURegister { |
195 enum Code { | 195 enum Code { |
196 #define REGISTER_CODE(R) kCode_##R, | 196 #define REGISTER_CODE(R) kCode_##R, |
197 DOUBLE_REGISTERS(REGISTER_CODE) | 197 DOUBLE_REGISTERS(REGISTER_CODE) |
198 #undef REGISTER_CODE | 198 #undef REGISTER_CODE |
199 kAfterLast, | 199 kAfterLast, |
200 kCode_no_reg = -1 | 200 kCode_no_reg = -1 |
201 }; | 201 }; |
202 | 202 |
203 static FPRegister Create(unsigned code, unsigned size) { | 203 static FPRegister Create(int code, int size) { |
204 return FPRegister( | 204 return FPRegister( |
205 CPURegister::Create(code, size, CPURegister::kFPRegister)); | 205 CPURegister::Create(code, size, CPURegister::kFPRegister)); |
206 } | 206 } |
207 | 207 |
208 FPRegister() { | 208 FPRegister() { |
209 reg_code = 0; | 209 reg_code = 0; |
210 reg_size = 0; | 210 reg_size = 0; |
211 reg_type = CPURegister::kNoRegister; | 211 reg_type = CPURegister::kNoRegister; |
212 } | 212 } |
213 | 213 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 explicit CPURegList(CPURegister reg1, | 378 explicit CPURegList(CPURegister reg1, |
379 CPURegister reg2 = NoCPUReg, | 379 CPURegister reg2 = NoCPUReg, |
380 CPURegister reg3 = NoCPUReg, | 380 CPURegister reg3 = NoCPUReg, |
381 CPURegister reg4 = NoCPUReg) | 381 CPURegister reg4 = NoCPUReg) |
382 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()), | 382 : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()), |
383 size_(reg1.SizeInBits()), type_(reg1.type()) { | 383 size_(reg1.SizeInBits()), type_(reg1.type()) { |
384 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4)); | 384 DCHECK(AreSameSizeAndType(reg1, reg2, reg3, reg4)); |
385 DCHECK(IsValid()); | 385 DCHECK(IsValid()); |
386 } | 386 } |
387 | 387 |
388 CPURegList(CPURegister::RegisterType type, unsigned size, RegList list) | 388 CPURegList(CPURegister::RegisterType type, int size, RegList list) |
389 : list_(list), size_(size), type_(type) { | 389 : list_(list), size_(size), type_(type) { |
390 DCHECK(IsValid()); | 390 DCHECK(IsValid()); |
391 } | 391 } |
392 | 392 |
393 CPURegList(CPURegister::RegisterType type, unsigned size, | 393 CPURegList(CPURegister::RegisterType type, int size, int first_reg, |
394 unsigned first_reg, unsigned last_reg) | 394 int last_reg) |
395 : size_(size), type_(type) { | 395 : size_(size), type_(type) { |
396 DCHECK(((type == CPURegister::kRegister) && | 396 DCHECK(((type == CPURegister::kRegister) && |
397 (last_reg < kNumberOfRegisters)) || | 397 (last_reg < kNumberOfRegisters)) || |
398 ((type == CPURegister::kFPRegister) && | 398 ((type == CPURegister::kFPRegister) && |
399 (last_reg < kNumberOfFPRegisters))); | 399 (last_reg < kNumberOfFPRegisters))); |
400 DCHECK(last_reg >= first_reg); | 400 DCHECK(last_reg >= first_reg); |
401 list_ = (1UL << (last_reg + 1)) - 1; | 401 list_ = (1UL << (last_reg + 1)) - 1; |
402 list_ &= ~((1UL << first_reg) - 1); | 402 list_ &= ~((1UL << first_reg) - 1); |
403 DCHECK(IsValid()); | 403 DCHECK(IsValid()); |
404 } | 404 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 void Remove(int code); | 441 void Remove(int code); |
442 | 442 |
443 // Remove all callee-saved registers from the list. This can be useful when | 443 // Remove all callee-saved registers from the list. This can be useful when |
444 // preparing registers for an AAPCS64 function call, for example. | 444 // preparing registers for an AAPCS64 function call, for example. |
445 void RemoveCalleeSaved(); | 445 void RemoveCalleeSaved(); |
446 | 446 |
447 CPURegister PopLowestIndex(); | 447 CPURegister PopLowestIndex(); |
448 CPURegister PopHighestIndex(); | 448 CPURegister PopHighestIndex(); |
449 | 449 |
450 // AAPCS64 callee-saved registers. | 450 // AAPCS64 callee-saved registers. |
451 static CPURegList GetCalleeSaved(unsigned size = kXRegSizeInBits); | 451 static CPURegList GetCalleeSaved(int size = kXRegSizeInBits); |
452 static CPURegList GetCalleeSavedFP(unsigned size = kDRegSizeInBits); | 452 static CPURegList GetCalleeSavedFP(int size = kDRegSizeInBits); |
453 | 453 |
454 // AAPCS64 caller-saved registers. Note that this includes lr. | 454 // AAPCS64 caller-saved registers. Note that this includes lr. |
455 static CPURegList GetCallerSaved(unsigned size = kXRegSizeInBits); | 455 static CPURegList GetCallerSaved(int size = kXRegSizeInBits); |
456 static CPURegList GetCallerSavedFP(unsigned size = kDRegSizeInBits); | 456 static CPURegList GetCallerSavedFP(int size = kDRegSizeInBits); |
457 | 457 |
458 // Registers saved as safepoints. | 458 // Registers saved as safepoints. |
459 static CPURegList GetSafepointSavedRegisters(); | 459 static CPURegList GetSafepointSavedRegisters(); |
460 | 460 |
461 bool IsEmpty() const { | 461 bool IsEmpty() const { |
462 DCHECK(IsValid()); | 462 DCHECK(IsValid()); |
463 return list_ == 0; | 463 return list_ == 0; |
464 } | 464 } |
465 | 465 |
466 bool IncludesAliasOf(const CPURegister& other1, | 466 bool IncludesAliasOf(const CPURegister& other1, |
467 const CPURegister& other2 = NoCPUReg, | 467 const CPURegister& other2 = NoCPUReg, |
468 const CPURegister& other3 = NoCPUReg, | 468 const CPURegister& other3 = NoCPUReg, |
469 const CPURegister& other4 = NoCPUReg) const { | 469 const CPURegister& other4 = NoCPUReg) const { |
470 DCHECK(IsValid()); | 470 DCHECK(IsValid()); |
471 RegList list = 0; | 471 RegList list = 0; |
472 if (!other1.IsNone() && (other1.type() == type_)) list |= other1.Bit(); | 472 if (!other1.IsNone() && (other1.type() == type_)) list |= other1.Bit(); |
473 if (!other2.IsNone() && (other2.type() == type_)) list |= other2.Bit(); | 473 if (!other2.IsNone() && (other2.type() == type_)) list |= other2.Bit(); |
474 if (!other3.IsNone() && (other3.type() == type_)) list |= other3.Bit(); | 474 if (!other3.IsNone() && (other3.type() == type_)) list |= other3.Bit(); |
475 if (!other4.IsNone() && (other4.type() == type_)) list |= other4.Bit(); | 475 if (!other4.IsNone() && (other4.type() == type_)) list |= other4.Bit(); |
476 return (list_ & list) != 0; | 476 return (list_ & list) != 0; |
477 } | 477 } |
478 | 478 |
479 int Count() const { | 479 int Count() const { |
480 DCHECK(IsValid()); | 480 DCHECK(IsValid()); |
481 return CountSetBits(list_, kRegListSizeInBits); | 481 return CountSetBits(list_, kRegListSizeInBits); |
482 } | 482 } |
483 | 483 |
484 unsigned RegisterSizeInBits() const { | 484 int RegisterSizeInBits() const { |
485 DCHECK(IsValid()); | 485 DCHECK(IsValid()); |
486 return size_; | 486 return size_; |
487 } | 487 } |
488 | 488 |
489 unsigned RegisterSizeInBytes() const { | 489 int RegisterSizeInBytes() const { |
490 int size_in_bits = RegisterSizeInBits(); | 490 int size_in_bits = RegisterSizeInBits(); |
491 DCHECK((size_in_bits % kBitsPerByte) == 0); | 491 DCHECK((size_in_bits % kBitsPerByte) == 0); |
492 return size_in_bits / kBitsPerByte; | 492 return size_in_bits / kBitsPerByte; |
493 } | 493 } |
494 | 494 |
495 unsigned TotalSizeInBytes() const { | 495 int TotalSizeInBytes() const { |
496 DCHECK(IsValid()); | 496 DCHECK(IsValid()); |
497 return RegisterSizeInBytes() * Count(); | 497 return RegisterSizeInBytes() * Count(); |
498 } | 498 } |
499 | 499 |
500 private: | 500 private: |
501 RegList list_; | 501 RegList list_; |
502 unsigned size_; | 502 int size_; |
503 CPURegister::RegisterType type_; | 503 CPURegister::RegisterType type_; |
504 | 504 |
505 bool IsValid() const { | 505 bool IsValid() const { |
506 const RegList kValidRegisters = 0x8000000ffffffff; | 506 const RegList kValidRegisters = 0x8000000ffffffff; |
507 const RegList kValidFPRegisters = 0x0000000ffffffff; | 507 const RegList kValidFPRegisters = 0x0000000ffffffff; |
508 switch (type_) { | 508 switch (type_) { |
509 case CPURegister::kRegister: | 509 case CPURegister::kRegister: |
510 return (list_ & kValidRegisters) == list_; | 510 return (list_ & kValidRegisters) == list_; |
511 case CPURegister::kFPRegister: | 511 case CPURegister::kFPRegister: |
512 return (list_ & kValidFPRegisters) == list_; | 512 return (list_ & kValidFPRegisters) == list_; |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 void lsrv(const Register& rd, const Register& rn, const Register& rm); | 1114 void lsrv(const Register& rd, const Register& rn, const Register& rm); |
1115 | 1115 |
1116 // Arithmetic shift right variable. | 1116 // Arithmetic shift right variable. |
1117 void asrv(const Register& rd, const Register& rn, const Register& rm); | 1117 void asrv(const Register& rd, const Register& rn, const Register& rm); |
1118 | 1118 |
1119 // Rotate right variable. | 1119 // Rotate right variable. |
1120 void rorv(const Register& rd, const Register& rn, const Register& rm); | 1120 void rorv(const Register& rd, const Register& rn, const Register& rm); |
1121 | 1121 |
1122 // Bitfield instructions. | 1122 // Bitfield instructions. |
1123 // Bitfield move. | 1123 // Bitfield move. |
1124 void bfm(const Register& rd, | 1124 void bfm(const Register& rd, const Register& rn, int immr, int imms); |
1125 const Register& rn, | |
1126 unsigned immr, | |
1127 unsigned imms); | |
1128 | 1125 |
1129 // Signed bitfield move. | 1126 // Signed bitfield move. |
1130 void sbfm(const Register& rd, | 1127 void sbfm(const Register& rd, const Register& rn, int immr, int imms); |
1131 const Register& rn, | |
1132 unsigned immr, | |
1133 unsigned imms); | |
1134 | 1128 |
1135 // Unsigned bitfield move. | 1129 // Unsigned bitfield move. |
1136 void ubfm(const Register& rd, | 1130 void ubfm(const Register& rd, const Register& rn, int immr, int imms); |
1137 const Register& rn, | |
1138 unsigned immr, | |
1139 unsigned imms); | |
1140 | 1131 |
1141 // Bfm aliases. | 1132 // Bfm aliases. |
1142 // Bitfield insert. | 1133 // Bitfield insert. |
1143 void bfi(const Register& rd, | 1134 void bfi(const Register& rd, const Register& rn, int lsb, int width) { |
1144 const Register& rn, | |
1145 unsigned lsb, | |
1146 unsigned width) { | |
1147 DCHECK(width >= 1); | 1135 DCHECK(width >= 1); |
1148 DCHECK(lsb + width <= rn.SizeInBits()); | 1136 DCHECK(lsb + width <= rn.SizeInBits()); |
1149 bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); | 1137 bfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); |
1150 } | 1138 } |
1151 | 1139 |
1152 // Bitfield extract and insert low. | 1140 // Bitfield extract and insert low. |
1153 void bfxil(const Register& rd, | 1141 void bfxil(const Register& rd, const Register& rn, int lsb, int width) { |
1154 const Register& rn, | |
1155 unsigned lsb, | |
1156 unsigned width) { | |
1157 DCHECK(width >= 1); | 1142 DCHECK(width >= 1); |
1158 DCHECK(lsb + width <= rn.SizeInBits()); | 1143 DCHECK(lsb + width <= rn.SizeInBits()); |
1159 bfm(rd, rn, lsb, lsb + width - 1); | 1144 bfm(rd, rn, lsb, lsb + width - 1); |
1160 } | 1145 } |
1161 | 1146 |
1162 // Sbfm aliases. | 1147 // Sbfm aliases. |
1163 // Arithmetic shift right. | 1148 // Arithmetic shift right. |
1164 void asr(const Register& rd, const Register& rn, unsigned shift) { | 1149 void asr(const Register& rd, const Register& rn, int shift) { |
1165 DCHECK(shift < rd.SizeInBits()); | 1150 DCHECK(shift < rd.SizeInBits()); |
1166 sbfm(rd, rn, shift, rd.SizeInBits() - 1); | 1151 sbfm(rd, rn, shift, rd.SizeInBits() - 1); |
1167 } | 1152 } |
1168 | 1153 |
1169 // Signed bitfield insert in zero. | 1154 // Signed bitfield insert in zero. |
1170 void sbfiz(const Register& rd, | 1155 void sbfiz(const Register& rd, const Register& rn, int lsb, int width) { |
1171 const Register& rn, | |
1172 unsigned lsb, | |
1173 unsigned width) { | |
1174 DCHECK(width >= 1); | 1156 DCHECK(width >= 1); |
1175 DCHECK(lsb + width <= rn.SizeInBits()); | 1157 DCHECK(lsb + width <= rn.SizeInBits()); |
1176 sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); | 1158 sbfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); |
1177 } | 1159 } |
1178 | 1160 |
1179 // Signed bitfield extract. | 1161 // Signed bitfield extract. |
1180 void sbfx(const Register& rd, | 1162 void sbfx(const Register& rd, const Register& rn, int lsb, int width) { |
1181 const Register& rn, | |
1182 unsigned lsb, | |
1183 unsigned width) { | |
1184 DCHECK(width >= 1); | 1163 DCHECK(width >= 1); |
1185 DCHECK(lsb + width <= rn.SizeInBits()); | 1164 DCHECK(lsb + width <= rn.SizeInBits()); |
1186 sbfm(rd, rn, lsb, lsb + width - 1); | 1165 sbfm(rd, rn, lsb, lsb + width - 1); |
1187 } | 1166 } |
1188 | 1167 |
1189 // Signed extend byte. | 1168 // Signed extend byte. |
1190 void sxtb(const Register& rd, const Register& rn) { | 1169 void sxtb(const Register& rd, const Register& rn) { |
1191 sbfm(rd, rn, 0, 7); | 1170 sbfm(rd, rn, 0, 7); |
1192 } | 1171 } |
1193 | 1172 |
1194 // Signed extend halfword. | 1173 // Signed extend halfword. |
1195 void sxth(const Register& rd, const Register& rn) { | 1174 void sxth(const Register& rd, const Register& rn) { |
1196 sbfm(rd, rn, 0, 15); | 1175 sbfm(rd, rn, 0, 15); |
1197 } | 1176 } |
1198 | 1177 |
1199 // Signed extend word. | 1178 // Signed extend word. |
1200 void sxtw(const Register& rd, const Register& rn) { | 1179 void sxtw(const Register& rd, const Register& rn) { |
1201 sbfm(rd, rn, 0, 31); | 1180 sbfm(rd, rn, 0, 31); |
1202 } | 1181 } |
1203 | 1182 |
1204 // Ubfm aliases. | 1183 // Ubfm aliases. |
1205 // Logical shift left. | 1184 // Logical shift left. |
1206 void lsl(const Register& rd, const Register& rn, unsigned shift) { | 1185 void lsl(const Register& rd, const Register& rn, int shift) { |
1207 unsigned reg_size = rd.SizeInBits(); | 1186 int reg_size = rd.SizeInBits(); |
1208 DCHECK(shift < reg_size); | 1187 DCHECK(shift < reg_size); |
1209 ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1); | 1188 ubfm(rd, rn, (reg_size - shift) % reg_size, reg_size - shift - 1); |
1210 } | 1189 } |
1211 | 1190 |
1212 // Logical shift right. | 1191 // Logical shift right. |
1213 void lsr(const Register& rd, const Register& rn, unsigned shift) { | 1192 void lsr(const Register& rd, const Register& rn, int shift) { |
1214 DCHECK(shift < rd.SizeInBits()); | 1193 DCHECK(shift < rd.SizeInBits()); |
1215 ubfm(rd, rn, shift, rd.SizeInBits() - 1); | 1194 ubfm(rd, rn, shift, rd.SizeInBits() - 1); |
1216 } | 1195 } |
1217 | 1196 |
1218 // Unsigned bitfield insert in zero. | 1197 // Unsigned bitfield insert in zero. |
1219 void ubfiz(const Register& rd, | 1198 void ubfiz(const Register& rd, const Register& rn, int lsb, int width) { |
1220 const Register& rn, | |
1221 unsigned lsb, | |
1222 unsigned width) { | |
1223 DCHECK(width >= 1); | 1199 DCHECK(width >= 1); |
1224 DCHECK(lsb + width <= rn.SizeInBits()); | 1200 DCHECK(lsb + width <= rn.SizeInBits()); |
1225 ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); | 1201 ubfm(rd, rn, (rd.SizeInBits() - lsb) & (rd.SizeInBits() - 1), width - 1); |
1226 } | 1202 } |
1227 | 1203 |
1228 // Unsigned bitfield extract. | 1204 // Unsigned bitfield extract. |
1229 void ubfx(const Register& rd, | 1205 void ubfx(const Register& rd, const Register& rn, int lsb, int width) { |
1230 const Register& rn, | |
1231 unsigned lsb, | |
1232 unsigned width) { | |
1233 DCHECK(width >= 1); | 1206 DCHECK(width >= 1); |
1234 DCHECK(lsb + width <= rn.SizeInBits()); | 1207 DCHECK(lsb + width <= rn.SizeInBits()); |
1235 ubfm(rd, rn, lsb, lsb + width - 1); | 1208 ubfm(rd, rn, lsb, lsb + width - 1); |
1236 } | 1209 } |
1237 | 1210 |
1238 // Unsigned extend byte. | 1211 // Unsigned extend byte. |
1239 void uxtb(const Register& rd, const Register& rn) { | 1212 void uxtb(const Register& rd, const Register& rn) { |
1240 ubfm(rd, rn, 0, 7); | 1213 ubfm(rd, rn, 0, 7); |
1241 } | 1214 } |
1242 | 1215 |
1243 // Unsigned extend halfword. | 1216 // Unsigned extend halfword. |
1244 void uxth(const Register& rd, const Register& rn) { | 1217 void uxth(const Register& rd, const Register& rn) { |
1245 ubfm(rd, rn, 0, 15); | 1218 ubfm(rd, rn, 0, 15); |
1246 } | 1219 } |
1247 | 1220 |
1248 // Unsigned extend word. | 1221 // Unsigned extend word. |
1249 void uxtw(const Register& rd, const Register& rn) { | 1222 void uxtw(const Register& rd, const Register& rn) { |
1250 ubfm(rd, rn, 0, 31); | 1223 ubfm(rd, rn, 0, 31); |
1251 } | 1224 } |
1252 | 1225 |
1253 // Extract. | 1226 // Extract. |
1254 void extr(const Register& rd, | 1227 void extr(const Register& rd, const Register& rn, const Register& rm, |
1255 const Register& rn, | 1228 int lsb); |
1256 const Register& rm, | |
1257 unsigned lsb); | |
1258 | 1229 |
1259 // Conditional select: rd = cond ? rn : rm. | 1230 // Conditional select: rd = cond ? rn : rm. |
1260 void csel(const Register& rd, | 1231 void csel(const Register& rd, |
1261 const Register& rn, | 1232 const Register& rn, |
1262 const Register& rm, | 1233 const Register& rm, |
1263 Condition cond); | 1234 Condition cond); |
1264 | 1235 |
1265 // Conditional select increment: rd = cond ? rn : rm + 1. | 1236 // Conditional select increment: rd = cond ? rn : rm + 1. |
1266 void csinc(const Register& rd, | 1237 void csinc(const Register& rd, |
1267 const Register& rn, | 1238 const Register& rn, |
(...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2217 public: | 2188 public: |
2218 explicit EnsureSpace(Assembler* assembler) { | 2189 explicit EnsureSpace(Assembler* assembler) { |
2219 assembler->CheckBufferSpace(); | 2190 assembler->CheckBufferSpace(); |
2220 } | 2191 } |
2221 }; | 2192 }; |
2222 | 2193 |
2223 } // namespace internal | 2194 } // namespace internal |
2224 } // namespace v8 | 2195 } // namespace v8 |
2225 | 2196 |
2226 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ | 2197 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ |
OLD | NEW |