• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_CODEGEN_LOONG64_CONSTANTS_LOONG64_H_
6 #define V8_CODEGEN_LOONG64_CONSTANTS_LOONG64_H_
7 
8 #include "src/base/logging.h"
9 #include "src/base/macros.h"
10 #include "src/common/globals.h"
11 
12 // Get the standard printf format macros for C99 stdint types.
13 #ifndef __STDC_FORMAT_MACROS
14 #define __STDC_FORMAT_MACROS
15 #endif
16 #include <inttypes.h>
17 
18 // Defines constants and accessor classes to assemble, disassemble and
19 // simulate LOONG64 instructions.
20 
21 namespace v8 {
22 namespace internal {
23 
24 constexpr size_t kMaxPCRelativeCodeRangeInMB = 128;
25 
26 // -----------------------------------------------------------------------------
27 // Registers and FPURegisters.
28 
29 // Number of general purpose registers.
30 const int kNumRegisters = 32;
31 const int kInvalidRegister = -1;
32 
33 // Number of registers with pc.
34 const int kNumSimuRegisters = 33;
35 
36 // In the simulator, the PC register is simulated as the 33th register.
37 const int kPCRegister = 32;
38 
39 // Number of floating point registers.
40 const int kNumFPURegisters = 32;
41 const int kInvalidFPURegister = -1;
42 
43 // FPU control registers.
44 const int kFCSRRegister = 0;
45 const int kInvalidFPUControlRegister = -1;
46 const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1u << 31) - 1;
47 const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1u << 31);
48 const uint64_t kFPU64InvalidResult =
49     static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
50 const int64_t kFPU64InvalidResultNegative =
51     static_cast<int64_t>(static_cast<uint64_t>(1) << 63);
52 
53 // FCSR constants.
54 const uint32_t kFCSRInexactCauseBit = 24;
55 const uint32_t kFCSRUnderflowCauseBit = 25;
56 const uint32_t kFCSROverflowCauseBit = 26;
57 const uint32_t kFCSRDivideByZeroCauseBit = 27;
58 const uint32_t kFCSRInvalidOpCauseBit = 28;
59 
60 const uint32_t kFCSRInexactCauseMask = 1 << kFCSRInexactCauseBit;
61 const uint32_t kFCSRUnderflowCauseMask = 1 << kFCSRUnderflowCauseBit;
62 const uint32_t kFCSROverflowCauseMask = 1 << kFCSROverflowCauseBit;
63 const uint32_t kFCSRDivideByZeroCauseMask = 1 << kFCSRDivideByZeroCauseBit;
64 const uint32_t kFCSRInvalidOpCauseMask = 1 << kFCSRInvalidOpCauseBit;
65 
66 const uint32_t kFCSRCauseMask =
67     kFCSRInexactCauseMask | kFCSRUnderflowCauseMask | kFCSROverflowCauseMask |
68     kFCSRDivideByZeroCauseMask | kFCSRInvalidOpCauseMask;
69 
70 const uint32_t kFCSRExceptionCauseMask = kFCSRCauseMask ^ kFCSRInexactCauseMask;
71 
72 // Actual value of root register is offset from the root array's start
73 // to take advantage of negative displacement values.
74 // TODO(sigurds): Choose best value.
75 constexpr int kRootRegisterBias = 256;
76 
77 // Helper functions for converting between register numbers and names.
78 class Registers {
79  public:
80   // Return the name of the register.
81   static const char* Name(int reg);
82 
83   // Lookup the register number for the name provided.
84   static int Number(const char* name);
85 
86   struct RegisterAlias {
87     int reg;
88     const char* name;
89   };
90 
91   static const int64_t kMaxValue = 0x7fffffffffffffffl;
92   static const int64_t kMinValue = 0x8000000000000000l;
93 
94  private:
95   static const char* names_[kNumSimuRegisters];
96   static const RegisterAlias aliases_[];
97 };
98 
99 // Helper functions for converting between register numbers and names.
100 class FPURegisters {
101  public:
102   // Return the name of the register.
103   static const char* Name(int reg);
104 
105   // Lookup the register number for the name provided.
106   static int Number(const char* name);
107 
108   struct RegisterAlias {
109     int creg;
110     const char* name;
111   };
112 
113  private:
114   static const char* names_[kNumFPURegisters];
115   static const RegisterAlias aliases_[];
116 };
117 
118 // -----------------------------------------------------------------------------
119 // Instructions encoding constants.
120 
121 // On LoongArch all instructions are 32 bits.
122 using Instr = int32_t;
123 
124 // Special Software Interrupt codes when used in the presence of the LOONG64
125 // simulator.
126 enum SoftwareInterruptCodes {
127   // Transition to C code.
128   call_rt_redirected = 0x7fff
129 };
130 
131 // On LOONG64 Simulator breakpoints can have different codes:
132 // - Breaks between 0 and kMaxWatchpointCode are treated as simple watchpoints,
133 //   the simulator will run through them and print the registers.
134 // - Breaks between kMaxWatchpointCode and kMaxStopCode are treated as stop()
135 //   instructions (see Assembler::stop()).
136 // - Breaks larger than kMaxStopCode are simple breaks, dropping you into the
137 //   debugger.
138 const uint32_t kMaxWatchpointCode = 31;
139 const uint32_t kMaxStopCode = 127;
140 STATIC_ASSERT(kMaxWatchpointCode < kMaxStopCode);
141 
142 // ----- Fields offset and length.
143 const int kRjShift = 5;
144 const int kRjBits = 5;
145 const int kRkShift = 10;
146 const int kRkBits = 5;
147 const int kRdShift = 0;
148 const int kRdBits = 5;
149 const int kSaShift = 15;
150 const int kSa2Bits = 2;
151 const int kSa3Bits = 3;
152 const int kCdShift = 0;
153 const int kCdBits = 3;
154 const int kCjShift = 5;
155 const int kCjBits = 3;
156 const int kCodeShift = 0;
157 const int kCodeBits = 15;
158 const int kCondShift = 15;
159 const int kCondBits = 5;
160 const int kUi5Shift = 10;
161 const int kUi5Bits = 5;
162 const int kUi6Shift = 10;
163 const int kUi6Bits = 6;
164 const int kUi12Shift = 10;
165 const int kUi12Bits = 12;
166 const int kSi12Shift = 10;
167 const int kSi12Bits = 12;
168 const int kSi14Shift = 10;
169 const int kSi14Bits = 14;
170 const int kSi16Shift = 10;
171 const int kSi16Bits = 16;
172 const int kSi20Shift = 5;
173 const int kSi20Bits = 20;
174 const int kMsbwShift = 16;
175 const int kMsbwBits = 5;
176 const int kLsbwShift = 10;
177 const int kLsbwBits = 5;
178 const int kMsbdShift = 16;
179 const int kMsbdBits = 6;
180 const int kLsbdShift = 10;
181 const int kLsbdBits = 6;
182 const int kFdShift = 0;
183 const int kFdBits = 5;
184 const int kFjShift = 5;
185 const int kFjBits = 5;
186 const int kFkShift = 10;
187 const int kFkBits = 5;
188 const int kFaShift = 15;
189 const int kFaBits = 5;
190 const int kCaShift = 15;
191 const int kCaBits = 3;
192 const int kHint15Shift = 0;
193 const int kHint15Bits = 15;
194 const int kHint5Shift = 0;
195 const int kHint5Bits = 5;
196 const int kOffsLowShift = 10;
197 const int kOffsLowBits = 16;
198 const int kOffs26HighShift = 0;
199 const int kOffs26HighBits = 10;
200 const int kOffs21HighShift = 0;
201 const int kOffs21HighBits = 5;
202 const int kImm12Shift = 0;
203 const int kImm12Bits = 12;
204 const int kImm16Shift = 0;
205 const int kImm16Bits = 16;
206 const int kImm26Shift = 0;
207 const int kImm26Bits = 26;
208 const int kImm28Shift = 0;
209 const int kImm28Bits = 28;
210 const int kImm32Shift = 0;
211 const int kImm32Bits = 32;
212 
213 // ----- Miscellaneous useful masks.
214 // Instruction bit masks.
215 const int kRjFieldMask = ((1 << kRjBits) - 1) << kRjShift;
216 const int kRkFieldMask = ((1 << kRkBits) - 1) << kRkShift;
217 const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
218 const int kSa2FieldMask = ((1 << kSa2Bits) - 1) << kSaShift;
219 const int kSa3FieldMask = ((1 << kSa3Bits) - 1) << kSaShift;
220 // Misc masks.
221 const int kHiMaskOf32 = 0xffff << 16;  // Only to be used with 32-bit values
222 const int kLoMaskOf32 = 0xffff;
223 const int kSignMaskOf32 = 0x80000000;  // Only to be used with 32-bit values
224 const int64_t kTop16MaskOf64 = (int64_t)0xffff << 48;
225 const int64_t kHigher16MaskOf64 = (int64_t)0xffff << 32;
226 const int64_t kUpper16MaskOf64 = (int64_t)0xffff << 16;
227 
228 const int kImm12Mask = ((1 << kImm12Bits) - 1) << kImm12Shift;
229 const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
230 const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
231 const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
232 
233 // ----- LOONG64 Opcodes and Function Fields.
234 enum Opcode : uint32_t {
235   BEQZ = 0x10U << 26,
236   BNEZ = 0x11U << 26,
237   BCZ = 0x12U << 26,  // BCEQZ & BCNEZ
238   JIRL = 0x13U << 26,
239   B = 0x14U << 26,
240   BL = 0x15U << 26,
241   BEQ = 0x16U << 26,
242   BNE = 0x17U << 26,
243   BLT = 0x18U << 26,
244   BGE = 0x19U << 26,
245   BLTU = 0x1aU << 26,
246   BGEU = 0x1bU << 26,
247 
248   ADDU16I_D = 0x4U << 26,
249 
250   LU12I_W = 0xaU << 25,
251   LU32I_D = 0xbU << 25,
252   PCADDI = 0xcU << 25,
253   PCALAU12I = 0xdU << 25,
254   PCADDU12I = 0xeU << 25,
255   PCADDU18I = 0xfU << 25,
256 
257   LL_W = 0x20U << 24,
258   SC_W = 0x21U << 24,
259   LL_D = 0x22U << 24,
260   SC_D = 0x23U << 24,
261   LDPTR_W = 0x24U << 24,
262   STPTR_W = 0x25U << 24,
263   LDPTR_D = 0x26U << 24,
264   STPTR_D = 0x27U << 24,
265 
266   BSTR_W = 0x1U << 22,  // BSTRINS_W & BSTRPICK_W
267   BSTRINS_W = BSTR_W,
268   BSTRPICK_W = BSTR_W,
269   BSTRINS_D = 0x2U << 22,
270   BSTRPICK_D = 0x3U << 22,
271 
272   SLTI = 0x8U << 22,
273   SLTUI = 0x9U << 22,
274   ADDI_W = 0xaU << 22,
275   ADDI_D = 0xbU << 22,
276   LU52I_D = 0xcU << 22,
277   ANDI = 0xdU << 22,
278   ORI = 0xeU << 22,
279   XORI = 0xfU << 22,
280 
281   LD_B = 0xa0U << 22,
282   LD_H = 0xa1U << 22,
283   LD_W = 0xa2U << 22,
284   LD_D = 0xa3U << 22,
285   ST_B = 0xa4U << 22,
286   ST_H = 0xa5U << 22,
287   ST_W = 0xa6U << 22,
288   ST_D = 0xa7U << 22,
289   LD_BU = 0xa8U << 22,
290   LD_HU = 0xa9U << 22,
291   LD_WU = 0xaaU << 22,
292   FLD_S = 0xacU << 22,
293   FST_S = 0xadU << 22,
294   FLD_D = 0xaeU << 22,
295   FST_D = 0xafU << 22,
296 
297   FMADD_S = 0x81U << 20,
298   FMADD_D = 0x82U << 20,
299   FMSUB_S = 0x85U << 20,
300   FMSUB_D = 0x86U << 20,
301   FNMADD_S = 0x89U << 20,
302   FNMADD_D = 0x8aU << 20,
303   FNMSUB_S = 0x8dU << 20,
304   FNMSUB_D = 0x8eU << 20,
305   FCMP_COND_S = 0xc1U << 20,
306   FCMP_COND_D = 0xc2U << 20,
307 
308   BYTEPICK_D = 0x3U << 18,
309   BYTEPICK_W = 0x2U << 18,
310 
311   FSEL = 0x340U << 18,
312 
313   ALSL = 0x1U << 18,
314   ALSL_W = ALSL,
315   ALSL_WU = ALSL,
316 
317   ALSL_D = 0xbU << 18,
318 
319   SLLI_W = 0x40U << 16,
320   SRLI_W = 0x44U << 16,
321   SRAI_W = 0x48U << 16,
322   ROTRI_W = 0x4cU << 16,
323 
324   SLLI_D = 0x41U << 16,
325   SRLI_D = 0x45U << 16,
326   SRAI_D = 0x49U << 16,
327   ROTRI_D = 0x4dU << 16,
328 
329   SLLI = 0x10U << 18,
330   SRLI = 0x11U << 18,
331   SRAI = 0x12U << 18,
332   ROTRI = 0x13U << 18,
333 
334   ADD_W = 0x20U << 15,
335   ADD_D = 0x21U << 15,
336   SUB_W = 0x22U << 15,
337   SUB_D = 0x23U << 15,
338   SLT = 0x24U << 15,
339   SLTU = 0x25U << 15,
340   MASKEQZ = 0x26U << 15,
341   MASKNEZ = 0x27U << 15,
342   NOR = 0x28U << 15,
343   AND = 0x29U << 15,
344   OR = 0x2aU << 15,
345   XOR = 0x2bU << 15,
346   ORN = 0x2cU << 15,
347   ANDN = 0x2dU << 15,
348   SLL_W = 0x2eU << 15,
349   SRL_W = 0x2fU << 15,
350   SRA_W = 0x30U << 15,
351   SLL_D = 0x31U << 15,
352   SRL_D = 0x32U << 15,
353   SRA_D = 0x33U << 15,
354   ROTR_W = 0x36U << 15,
355   ROTR_D = 0x37U << 15,
356   MUL_W = 0x38U << 15,
357   MULH_W = 0x39U << 15,
358   MULH_WU = 0x3aU << 15,
359   MUL_D = 0x3bU << 15,
360   MULH_D = 0x3cU << 15,
361   MULH_DU = 0x3dU << 15,
362   MULW_D_W = 0x3eU << 15,
363   MULW_D_WU = 0x3fU << 15,
364 
365   DIV_W = 0x40U << 15,
366   MOD_W = 0x41U << 15,
367   DIV_WU = 0x42U << 15,
368   MOD_WU = 0x43U << 15,
369   DIV_D = 0x44U << 15,
370   MOD_D = 0x45U << 15,
371   DIV_DU = 0x46U << 15,
372   MOD_DU = 0x47U << 15,
373 
374   BREAK = 0x54U << 15,
375 
376   FADD_S = 0x201U << 15,
377   FADD_D = 0x202U << 15,
378   FSUB_S = 0x205U << 15,
379   FSUB_D = 0x206U << 15,
380   FMUL_S = 0x209U << 15,
381   FMUL_D = 0x20aU << 15,
382   FDIV_S = 0x20dU << 15,
383   FDIV_D = 0x20eU << 15,
384   FMAX_S = 0x211U << 15,
385   FMAX_D = 0x212U << 15,
386   FMIN_S = 0x215U << 15,
387   FMIN_D = 0x216U << 15,
388   FMAXA_S = 0x219U << 15,
389   FMAXA_D = 0x21aU << 15,
390   FMINA_S = 0x21dU << 15,
391   FMINA_D = 0x21eU << 15,
392   FSCALEB_S = 0x221U << 15,
393   FSCALEB_D = 0x222U << 15,
394   FCOPYSIGN_S = 0x225U << 15,
395   FCOPYSIGN_D = 0x226U << 15,
396 
397   LDX_B = 0x7000U << 15,
398   LDX_H = 0x7008U << 15,
399   LDX_W = 0x7010U << 15,
400   LDX_D = 0x7018U << 15,
401   STX_B = 0x7020U << 15,
402   STX_H = 0x7028U << 15,
403   STX_W = 0x7030U << 15,
404   STX_D = 0x7038U << 15,
405   LDX_BU = 0x7040U << 15,
406   LDX_HU = 0x7048U << 15,
407   LDX_WU = 0x7050U << 15,
408   FLDX_S = 0x7060U << 15,
409   FLDX_D = 0x7068U << 15,
410   FSTX_S = 0x7070U << 15,
411   FSTX_D = 0x7078U << 15,
412 
413   AMSWAP_W = 0x70c0U << 15,
414   AMSWAP_D = 0x70c1U << 15,
415   AMADD_W = 0x70c2U << 15,
416   AMADD_D = 0x70c3U << 15,
417   AMAND_W = 0x70c4U << 15,
418   AMAND_D = 0x70c5U << 15,
419   AMOR_W = 0x70c6U << 15,
420   AMOR_D = 0x70c7U << 15,
421   AMXOR_W = 0x70c8U << 15,
422   AMXOR_D = 0x70c9U << 15,
423   AMMAX_W = 0x70caU << 15,
424   AMMAX_D = 0x70cbU << 15,
425   AMMIN_W = 0x70ccU << 15,
426   AMMIN_D = 0x70cdU << 15,
427   AMMAX_WU = 0x70ceU << 15,
428   AMMAX_DU = 0x70cfU << 15,
429   AMMIN_WU = 0x70d0U << 15,
430   AMMIN_DU = 0x70d1U << 15,
431   AMSWAP_DB_W = 0x70d2U << 15,
432   AMSWAP_DB_D = 0x70d3U << 15,
433   AMADD_DB_W = 0x70d4U << 15,
434   AMADD_DB_D = 0x70d5U << 15,
435   AMAND_DB_W = 0x70d6U << 15,
436   AMAND_DB_D = 0x70d7U << 15,
437   AMOR_DB_W = 0x70d8U << 15,
438   AMOR_DB_D = 0x70d9U << 15,
439   AMXOR_DB_W = 0x70daU << 15,
440   AMXOR_DB_D = 0x70dbU << 15,
441   AMMAX_DB_W = 0x70dcU << 15,
442   AMMAX_DB_D = 0x70ddU << 15,
443   AMMIN_DB_W = 0x70deU << 15,
444   AMMIN_DB_D = 0x70dfU << 15,
445   AMMAX_DB_WU = 0x70e0U << 15,
446   AMMAX_DB_DU = 0x70e1U << 15,
447   AMMIN_DB_WU = 0x70e2U << 15,
448   AMMIN_DB_DU = 0x70e3U << 15,
449 
450   DBAR = 0x70e4U << 15,
451   IBAR = 0x70e5U << 15,
452 
453   CLO_W = 0X4U << 10,
454   CLZ_W = 0X5U << 10,
455   CTO_W = 0X6U << 10,
456   CTZ_W = 0X7U << 10,
457   CLO_D = 0X8U << 10,
458   CLZ_D = 0X9U << 10,
459   CTO_D = 0XaU << 10,
460   CTZ_D = 0XbU << 10,
461   REVB_2H = 0XcU << 10,
462   REVB_4H = 0XdU << 10,
463   REVB_2W = 0XeU << 10,
464   REVB_D = 0XfU << 10,
465   REVH_2W = 0X10U << 10,
466   REVH_D = 0X11U << 10,
467   BITREV_4B = 0X12U << 10,
468   BITREV_8B = 0X13U << 10,
469   BITREV_W = 0X14U << 10,
470   BITREV_D = 0X15U << 10,
471   EXT_W_H = 0X16U << 10,
472   EXT_W_B = 0X17U << 10,
473 
474   FABS_S = 0X4501U << 10,
475   FABS_D = 0X4502U << 10,
476   FNEG_S = 0X4505U << 10,
477   FNEG_D = 0X4506U << 10,
478   FLOGB_S = 0X4509U << 10,
479   FLOGB_D = 0X450aU << 10,
480   FCLASS_S = 0X450dU << 10,
481   FCLASS_D = 0X450eU << 10,
482   FSQRT_S = 0X4511U << 10,
483   FSQRT_D = 0X4512U << 10,
484   FRECIP_S = 0X4515U << 10,
485   FRECIP_D = 0X4516U << 10,
486   FRSQRT_S = 0X4519U << 10,
487   FRSQRT_D = 0X451aU << 10,
488   FMOV_S = 0X4525U << 10,
489   FMOV_D = 0X4526U << 10,
490   MOVGR2FR_W = 0X4529U << 10,
491   MOVGR2FR_D = 0X452aU << 10,
492   MOVGR2FRH_W = 0X452bU << 10,
493   MOVFR2GR_S = 0X452dU << 10,
494   MOVFR2GR_D = 0X452eU << 10,
495   MOVFRH2GR_S = 0X452fU << 10,
496   MOVGR2FCSR = 0X4530U << 10,
497   MOVFCSR2GR = 0X4532U << 10,
498   MOVFR2CF = 0X4534U << 10,
499   MOVGR2CF = 0X4536U << 10,
500 
501   FCVT_S_D = 0x4646U << 10,
502   FCVT_D_S = 0x4649U << 10,
503   FTINTRM_W_S = 0x4681U << 10,
504   FTINTRM_W_D = 0x4682U << 10,
505   FTINTRM_L_S = 0x4689U << 10,
506   FTINTRM_L_D = 0x468aU << 10,
507   FTINTRP_W_S = 0x4691U << 10,
508   FTINTRP_W_D = 0x4692U << 10,
509   FTINTRP_L_S = 0x4699U << 10,
510   FTINTRP_L_D = 0x469aU << 10,
511   FTINTRZ_W_S = 0x46a1U << 10,
512   FTINTRZ_W_D = 0x46a2U << 10,
513   FTINTRZ_L_S = 0x46a9U << 10,
514   FTINTRZ_L_D = 0x46aaU << 10,
515   FTINTRNE_W_S = 0x46b1U << 10,
516   FTINTRNE_W_D = 0x46b2U << 10,
517   FTINTRNE_L_S = 0x46b9U << 10,
518   FTINTRNE_L_D = 0x46baU << 10,
519   FTINT_W_S = 0x46c1U << 10,
520   FTINT_W_D = 0x46c2U << 10,
521   FTINT_L_S = 0x46c9U << 10,
522   FTINT_L_D = 0x46caU << 10,
523   FFINT_S_W = 0x4744U << 10,
524   FFINT_S_L = 0x4746U << 10,
525   FFINT_D_W = 0x4748U << 10,
526   FFINT_D_L = 0x474aU << 10,
527   FRINT_S = 0x4791U << 10,
528   FRINT_D = 0x4792U << 10,
529 
530   MOVCF2FR = 0x4535U << 10,
531   MOVCF2GR = 0x4537U << 10
532 };
533 
534 // ----- Emulated conditions.
535 // On LOONG64 we use this enum to abstract from conditional branch instructions.
536 // The 'U' prefix is used to specify unsigned comparisons.
537 enum Condition {
538   // Any value < 0 is considered no_condition.
539   kNoCondition = -1,
540   overflow = 0,
541   no_overflow = 1,
542   Uless = 2,
543   Ugreater_equal = 3,
544   Uless_equal = 4,
545   Ugreater = 5,
546   equal = 6,
547   not_equal = 7,  // Unordered or Not Equal.
548   negative = 8,
549   positive = 9,
550   parity_even = 10,
551   parity_odd = 11,
552   less = 12,
553   greater_equal = 13,
554   less_equal = 14,
555   greater = 15,
556   ueq = 16,  // Unordered or Equal.
557   ogl = 17,  // Ordered and Not Equal.
558   cc_always = 18,
559 
560   // Aliases.
561   carry = Uless,
562   not_carry = Ugreater_equal,
563   zero = equal,
564   eq = equal,
565   not_zero = not_equal,
566   ne = not_equal,
567   nz = not_equal,
568   sign = negative,
569   not_sign = positive,
570   mi = negative,
571   pl = positive,
572   hi = Ugreater,
573   ls = Uless_equal,
574   ge = greater_equal,
575   lt = less,
576   gt = greater,
577   le = less_equal,
578   hs = Ugreater_equal,
579   lo = Uless,
580   al = cc_always,
581   ult = Uless,
582   uge = Ugreater_equal,
583   ule = Uless_equal,
584   ugt = Ugreater,
585   cc_default = kNoCondition
586 };
587 
588 // Returns the equivalent of !cc.
589 // Negation of the default kNoCondition (-1) results in a non-default
590 // no_condition value (-2). As long as tests for no_condition check
591 // for condition < 0, this will work as expected.
NegateCondition(Condition cc)592 inline Condition NegateCondition(Condition cc) {
593   DCHECK(cc != cc_always);
594   return static_cast<Condition>(cc ^ 1);
595 }
596 
NegateFpuCondition(Condition cc)597 inline Condition NegateFpuCondition(Condition cc) {
598   DCHECK(cc != cc_always);
599   switch (cc) {
600     case ult:
601       return ge;
602     case ugt:
603       return le;
604     case uge:
605       return lt;
606     case ule:
607       return gt;
608     case lt:
609       return uge;
610     case gt:
611       return ule;
612     case ge:
613       return ult;
614     case le:
615       return ugt;
616     case eq:
617       return ne;
618     case ne:
619       return eq;
620     case ueq:
621       return ogl;
622     case ogl:
623       return ueq;
624     default:
625       return cc;
626   }
627 }
628 
629 // ----- Coprocessor conditions.
630 enum FPUCondition {
631   kNoFPUCondition = -1,
632 
633   CAF = 0x00,  // False.
634   SAF = 0x01,  // False.
635   CLT = 0x02,  // Less Than quiet
636                //  SLT  = 0x03,    // Less Than signaling
637   CEQ = 0x04,
638   SEQ = 0x05,
639   CLE = 0x06,
640   SLE = 0x07,
641   CUN = 0x08,
642   SUN = 0x09,
643   CULT = 0x0a,
644   SULT = 0x0b,
645   CUEQ = 0x0c,
646   SUEQ = 0x0d,
647   CULE = 0x0e,
648   SULE = 0x0f,
649   CNE = 0x10,
650   SNE = 0x11,
651   COR = 0x14,
652   SOR = 0x15,
653   CUNE = 0x18,
654   SUNE = 0x19,
655 };
656 
657 const uint32_t kFPURoundingModeShift = 8;
658 const uint32_t kFPURoundingModeMask = 0b11 << kFPURoundingModeShift;
659 
660 // FPU rounding modes.
661 enum FPURoundingMode {
662   RN = 0b00 << kFPURoundingModeShift,  // Round to Nearest.
663   RZ = 0b01 << kFPURoundingModeShift,  // Round towards zero.
664   RP = 0b10 << kFPURoundingModeShift,  // Round towards Plus Infinity.
665   RM = 0b11 << kFPURoundingModeShift,  // Round towards Minus Infinity.
666 
667   // Aliases.
668   kRoundToNearest = RN,
669   kRoundToZero = RZ,
670   kRoundToPlusInf = RP,
671   kRoundToMinusInf = RM,
672 
673   mode_round = RN,
674   mode_ceil = RP,
675   mode_floor = RM,
676   mode_trunc = RZ
677 };
678 
679 enum CheckForInexactConversion {
680   kCheckForInexactConversion,
681   kDontCheckForInexactConversion
682 };
683 
684 enum class MaxMinKind : int { kMin = 0, kMax = 1 };
685 
686 // -----------------------------------------------------------------------------
687 // Hints.
688 
689 // Branch hints are not used on the LOONG64.  They are defined so that they can
690 // appear in shared function signatures, but will be ignored in LOONG64
691 // implementations.
692 enum Hint { no_hint = 0 };
693 
NegateHint(Hint hint)694 inline Hint NegateHint(Hint hint) { return no_hint; }
695 
696 // -----------------------------------------------------------------------------
697 // Specific instructions, constants, and masks.
698 // These constants are declared in assembler-loong64.cc, as they use named
699 // registers and other constants.
700 
701 // Break 0xfffff, reserved for redirected real time call.
702 const Instr rtCallRedirInstr = BREAK | call_rt_redirected;
703 // A nop instruction. (Encoding of addi_w 0 0 0).
704 const Instr nopInstr = ADDI_W;
705 
706 constexpr uint8_t kInstrSize = 4;
707 constexpr uint8_t kInstrSizeLog2 = 2;
708 
709 class InstructionBase {
710  public:
711   enum Type {
712     kOp6Type,
713     kOp7Type,
714     kOp8Type,
715     kOp10Type,
716     kOp12Type,
717     kOp14Type,
718     kOp17Type,
719     kOp22Type,
720     kUnsupported = -1
721   };
722 
723   // Get the raw instruction bits.
InstructionBits()724   inline Instr InstructionBits() const {
725     return *reinterpret_cast<const Instr*>(this);
726   }
727 
728   // Set the raw instruction bits to value.
SetInstructionBits(Instr value)729   inline void SetInstructionBits(Instr value) {
730     *reinterpret_cast<Instr*>(this) = value;
731   }
732 
733   // Read one particular bit out of the instruction bits.
Bit(int nr)734   inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
735 
736   // Read a bit field out of the instruction bits.
Bits(int hi,int lo)737   inline int Bits(int hi, int lo) const {
738     return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
739   }
740 
741   // Safe to call within InstructionType().
RjFieldRawNoAssert()742   inline int RjFieldRawNoAssert() const {
743     return InstructionBits() & kRjFieldMask;
744   }
745 
746   // Get the encoding type of the instruction.
747   inline Type InstructionType() const;
748 
749  protected:
InstructionBase()750   InstructionBase() {}
751 };
752 
753 template <class T>
754 class InstructionGetters : public T {
755  public:
RjValue()756   inline int RjValue() const {
757     return this->Bits(kRjShift + kRjBits - 1, kRjShift);
758   }
759 
RkValue()760   inline int RkValue() const {
761     return this->Bits(kRkShift + kRkBits - 1, kRkShift);
762   }
763 
RdValue()764   inline int RdValue() const {
765     return this->Bits(kRdShift + kRdBits - 1, kRdShift);
766   }
767 
Sa2Value()768   inline int Sa2Value() const {
769     return this->Bits(kSaShift + kSa2Bits - 1, kSaShift);
770   }
771 
Sa3Value()772   inline int Sa3Value() const {
773     return this->Bits(kSaShift + kSa3Bits - 1, kSaShift);
774   }
775 
Ui5Value()776   inline int Ui5Value() const {
777     return this->Bits(kUi5Shift + kUi5Bits - 1, kUi5Shift);
778   }
779 
Ui6Value()780   inline int Ui6Value() const {
781     return this->Bits(kUi6Shift + kUi6Bits - 1, kUi6Shift);
782   }
783 
Ui12Value()784   inline int Ui12Value() const {
785     return this->Bits(kUi12Shift + kUi12Bits - 1, kUi12Shift);
786   }
787 
LsbwValue()788   inline int LsbwValue() const {
789     return this->Bits(kLsbwShift + kLsbwBits - 1, kLsbwShift);
790   }
791 
MsbwValue()792   inline int MsbwValue() const {
793     return this->Bits(kMsbwShift + kMsbwBits - 1, kMsbwShift);
794   }
795 
LsbdValue()796   inline int LsbdValue() const {
797     return this->Bits(kLsbdShift + kLsbdBits - 1, kLsbdShift);
798   }
799 
MsbdValue()800   inline int MsbdValue() const {
801     return this->Bits(kMsbdShift + kMsbdBits - 1, kMsbdShift);
802   }
803 
CondValue()804   inline int CondValue() const {
805     return this->Bits(kCondShift + kCondBits - 1, kCondShift);
806   }
807 
Si12Value()808   inline int Si12Value() const {
809     return this->Bits(kSi12Shift + kSi12Bits - 1, kSi12Shift);
810   }
811 
Si14Value()812   inline int Si14Value() const {
813     return this->Bits(kSi14Shift + kSi14Bits - 1, kSi14Shift);
814   }
815 
Si16Value()816   inline int Si16Value() const {
817     return this->Bits(kSi16Shift + kSi16Bits - 1, kSi16Shift);
818   }
819 
Si20Value()820   inline int Si20Value() const {
821     return this->Bits(kSi20Shift + kSi20Bits - 1, kSi20Shift);
822   }
823 
FdValue()824   inline int FdValue() const {
825     return this->Bits(kFdShift + kFdBits - 1, kFdShift);
826   }
827 
FaValue()828   inline int FaValue() const {
829     return this->Bits(kFaShift + kFaBits - 1, kFaShift);
830   }
831 
FjValue()832   inline int FjValue() const {
833     return this->Bits(kFjShift + kFjBits - 1, kFjShift);
834   }
835 
FkValue()836   inline int FkValue() const {
837     return this->Bits(kFkShift + kFkBits - 1, kFkShift);
838   }
839 
CjValue()840   inline int CjValue() const {
841     return this->Bits(kCjShift + kCjBits - 1, kCjShift);
842   }
843 
CdValue()844   inline int CdValue() const {
845     return this->Bits(kCdShift + kCdBits - 1, kCdShift);
846   }
847 
CaValue()848   inline int CaValue() const {
849     return this->Bits(kCaShift + kCaBits - 1, kCaShift);
850   }
851 
CodeValue()852   inline int CodeValue() const {
853     return this->Bits(kCodeShift + kCodeBits - 1, kCodeShift);
854   }
855 
Hint5Value()856   inline int Hint5Value() const {
857     return this->Bits(kHint5Shift + kHint5Bits - 1, kHint5Shift);
858   }
859 
Hint15Value()860   inline int Hint15Value() const {
861     return this->Bits(kHint15Shift + kHint15Bits - 1, kHint15Shift);
862   }
863 
Offs16Value()864   inline int Offs16Value() const {
865     return this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
866   }
867 
Offs21Value()868   inline int Offs21Value() const {
869     int low = this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
870     int high =
871         this->Bits(kOffs21HighShift + kOffs21HighBits - 1, kOffs21HighShift);
872     return ((high << kOffsLowBits) + low);
873   }
874 
Offs26Value()875   inline int Offs26Value() const {
876     int low = this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
877     int high =
878         this->Bits(kOffs26HighShift + kOffs26HighBits - 1, kOffs26HighShift);
879     return ((high << kOffsLowBits) + low);
880   }
881 
RjFieldRaw()882   inline int RjFieldRaw() const {
883     return this->InstructionBits() & kRjFieldMask;
884   }
885 
RkFieldRaw()886   inline int RkFieldRaw() const {
887     return this->InstructionBits() & kRkFieldMask;
888   }
889 
RdFieldRaw()890   inline int RdFieldRaw() const {
891     return this->InstructionBits() & kRdFieldMask;
892   }
893 
ImmValue(int bits)894   inline int32_t ImmValue(int bits) const { return this->Bits(bits - 1, 0); }
895 
896   /*TODO*/
Imm12Value()897   inline int32_t Imm12Value() const { abort(); }
898 
Imm14Value()899   inline int32_t Imm14Value() const { abort(); }
900 
Imm16Value()901   inline int32_t Imm16Value() const { abort(); }
902 
903   // Say if the instruction is a break.
904   bool IsTrap() const;
905 };
906 
907 class Instruction : public InstructionGetters<InstructionBase> {
908  public:
909   // Instructions are read of out a code stream. The only way to get a
910   // reference to an instruction is to convert a pointer. There is no way
911   // to allocate or create instances of class Instruction.
912   // Use the At(pc) function to create references to Instruction.
At(byte * pc)913   static Instruction* At(byte* pc) {
914     return reinterpret_cast<Instruction*>(pc);
915   }
916 
917  private:
918   // We need to prevent the creation of instances of class Instruction.
919   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
920 };
921 
922 // -----------------------------------------------------------------------------
923 // LOONG64 assembly various constants.
924 
925 const int kInvalidStackOffset = -1;
926 
927 static const int kNegOffset = 0x00008000;
928 
InstructionType()929 InstructionBase::Type InstructionBase::InstructionType() const {
930   InstructionBase::Type kType = kUnsupported;
931 
932   // Check for kOp6Type
933   switch (Bits(31, 26) << 26) {
934     case ADDU16I_D:
935     case BEQZ:
936     case BNEZ:
937     case BCZ:
938     case JIRL:
939     case B:
940     case BL:
941     case BEQ:
942     case BNE:
943     case BLT:
944     case BGE:
945     case BLTU:
946     case BGEU:
947       kType = kOp6Type;
948       break;
949     default:
950       kType = kUnsupported;
951   }
952 
953   if (kType == kUnsupported) {
954     // Check for kOp7Type
955     switch (Bits(31, 25) << 25) {
956       case LU12I_W:
957       case LU32I_D:
958       case PCADDI:
959       case PCALAU12I:
960       case PCADDU12I:
961       case PCADDU18I:
962         kType = kOp7Type;
963         break;
964       default:
965         kType = kUnsupported;
966     }
967   }
968 
969   if (kType == kUnsupported) {
970     // Check for kOp8Type
971     switch (Bits(31, 24) << 24) {
972       case LDPTR_W:
973       case STPTR_W:
974       case LDPTR_D:
975       case STPTR_D:
976       case LL_W:
977       case SC_W:
978       case LL_D:
979       case SC_D:
980         kType = kOp8Type;
981         break;
982       default:
983         kType = kUnsupported;
984     }
985   }
986 
987   if (kType == kUnsupported) {
988     // Check for kOp10Type
989     switch (Bits(31, 22) << 22) {
990       case BSTR_W: {
991         // If Bit(21) = 0, then the Opcode is not BSTR_W.
992         if (Bit(21) == 0)
993           kType = kUnsupported;
994         else
995           kType = kOp10Type;
996         break;
997       }
998       case BSTRINS_D:
999       case BSTRPICK_D:
1000       case SLTI:
1001       case SLTUI:
1002       case ADDI_W:
1003       case ADDI_D:
1004       case LU52I_D:
1005       case ANDI:
1006       case ORI:
1007       case XORI:
1008       case LD_B:
1009       case LD_H:
1010       case LD_W:
1011       case LD_D:
1012       case ST_B:
1013       case ST_H:
1014       case ST_W:
1015       case ST_D:
1016       case LD_BU:
1017       case LD_HU:
1018       case LD_WU:
1019       case FLD_S:
1020       case FST_S:
1021       case FLD_D:
1022       case FST_D:
1023         kType = kOp10Type;
1024         break;
1025       default:
1026         kType = kUnsupported;
1027     }
1028   }
1029 
1030   if (kType == kUnsupported) {
1031     // Check for kOp12Type
1032     switch (Bits(31, 20) << 20) {
1033       case FMADD_S:
1034       case FMADD_D:
1035       case FMSUB_S:
1036       case FMSUB_D:
1037       case FNMADD_S:
1038       case FNMADD_D:
1039       case FNMSUB_S:
1040       case FNMSUB_D:
1041       case FCMP_COND_S:
1042       case FCMP_COND_D:
1043       case FSEL:
1044         kType = kOp12Type;
1045         break;
1046       default:
1047         kType = kUnsupported;
1048     }
1049   }
1050 
1051   if (kType == kUnsupported) {
1052     // Check for kOp14Type
1053     switch (Bits(31, 18) << 18) {
1054       case ALSL:
1055       case BYTEPICK_W:
1056       case BYTEPICK_D:
1057       case ALSL_D:
1058       case SLLI:
1059       case SRLI:
1060       case SRAI:
1061       case ROTRI:
1062         kType = kOp14Type;
1063         break;
1064       default:
1065         kType = kUnsupported;
1066     }
1067   }
1068 
1069   if (kType == kUnsupported) {
1070     // Check for kOp17Type
1071     switch (Bits(31, 15) << 15) {
1072       case ADD_W:
1073       case ADD_D:
1074       case SUB_W:
1075       case SUB_D:
1076       case SLT:
1077       case SLTU:
1078       case MASKEQZ:
1079       case MASKNEZ:
1080       case NOR:
1081       case AND:
1082       case OR:
1083       case XOR:
1084       case ORN:
1085       case ANDN:
1086       case SLL_W:
1087       case SRL_W:
1088       case SRA_W:
1089       case SLL_D:
1090       case SRL_D:
1091       case SRA_D:
1092       case ROTR_D:
1093       case ROTR_W:
1094       case MUL_W:
1095       case MULH_W:
1096       case MULH_WU:
1097       case MUL_D:
1098       case MULH_D:
1099       case MULH_DU:
1100       case MULW_D_W:
1101       case MULW_D_WU:
1102       case DIV_W:
1103       case MOD_W:
1104       case DIV_WU:
1105       case MOD_WU:
1106       case DIV_D:
1107       case MOD_D:
1108       case DIV_DU:
1109       case MOD_DU:
1110       case BREAK:
1111       case FADD_S:
1112       case FADD_D:
1113       case FSUB_S:
1114       case FSUB_D:
1115       case FMUL_S:
1116       case FMUL_D:
1117       case FDIV_S:
1118       case FDIV_D:
1119       case FMAX_S:
1120       case FMAX_D:
1121       case FMIN_S:
1122       case FMIN_D:
1123       case FMAXA_S:
1124       case FMAXA_D:
1125       case FMINA_S:
1126       case FMINA_D:
1127       case LDX_B:
1128       case LDX_H:
1129       case LDX_W:
1130       case LDX_D:
1131       case STX_B:
1132       case STX_H:
1133       case STX_W:
1134       case STX_D:
1135       case LDX_BU:
1136       case LDX_HU:
1137       case LDX_WU:
1138       case FLDX_S:
1139       case FLDX_D:
1140       case FSTX_S:
1141       case FSTX_D:
1142       case AMSWAP_W:
1143       case AMSWAP_D:
1144       case AMADD_W:
1145       case AMADD_D:
1146       case AMAND_W:
1147       case AMAND_D:
1148       case AMOR_W:
1149       case AMOR_D:
1150       case AMXOR_W:
1151       case AMXOR_D:
1152       case AMMAX_W:
1153       case AMMAX_D:
1154       case AMMIN_W:
1155       case AMMIN_D:
1156       case AMMAX_WU:
1157       case AMMAX_DU:
1158       case AMMIN_WU:
1159       case AMMIN_DU:
1160       case AMSWAP_DB_W:
1161       case AMSWAP_DB_D:
1162       case AMADD_DB_W:
1163       case AMADD_DB_D:
1164       case AMAND_DB_W:
1165       case AMAND_DB_D:
1166       case AMOR_DB_W:
1167       case AMOR_DB_D:
1168       case AMXOR_DB_W:
1169       case AMXOR_DB_D:
1170       case AMMAX_DB_W:
1171       case AMMAX_DB_D:
1172       case AMMIN_DB_W:
1173       case AMMIN_DB_D:
1174       case AMMAX_DB_WU:
1175       case AMMAX_DB_DU:
1176       case AMMIN_DB_WU:
1177       case AMMIN_DB_DU:
1178       case DBAR:
1179       case IBAR:
1180       case FSCALEB_S:
1181       case FSCALEB_D:
1182       case FCOPYSIGN_S:
1183       case FCOPYSIGN_D:
1184         kType = kOp17Type;
1185         break;
1186       default:
1187         kType = kUnsupported;
1188     }
1189   }
1190 
1191   if (kType == kUnsupported) {
1192     // Check for kOp22Type
1193     switch (Bits(31, 10) << 10) {
1194       case CLZ_W:
1195       case CTZ_W:
1196       case CLZ_D:
1197       case CTZ_D:
1198       case REVB_2H:
1199       case REVB_4H:
1200       case REVB_2W:
1201       case REVB_D:
1202       case REVH_2W:
1203       case REVH_D:
1204       case BITREV_4B:
1205       case BITREV_8B:
1206       case BITREV_W:
1207       case BITREV_D:
1208       case EXT_W_B:
1209       case EXT_W_H:
1210       case FABS_S:
1211       case FABS_D:
1212       case FNEG_S:
1213       case FNEG_D:
1214       case FSQRT_S:
1215       case FSQRT_D:
1216       case FMOV_S:
1217       case FMOV_D:
1218       case MOVGR2FR_W:
1219       case MOVGR2FR_D:
1220       case MOVGR2FRH_W:
1221       case MOVFR2GR_S:
1222       case MOVFR2GR_D:
1223       case MOVFRH2GR_S:
1224       case MOVGR2FCSR:
1225       case MOVFCSR2GR:
1226       case FCVT_S_D:
1227       case FCVT_D_S:
1228       case FTINTRM_W_S:
1229       case FTINTRM_W_D:
1230       case FTINTRM_L_S:
1231       case FTINTRM_L_D:
1232       case FTINTRP_W_S:
1233       case FTINTRP_W_D:
1234       case FTINTRP_L_S:
1235       case FTINTRP_L_D:
1236       case FTINTRZ_W_S:
1237       case FTINTRZ_W_D:
1238       case FTINTRZ_L_S:
1239       case FTINTRZ_L_D:
1240       case FTINTRNE_W_S:
1241       case FTINTRNE_W_D:
1242       case FTINTRNE_L_S:
1243       case FTINTRNE_L_D:
1244       case FTINT_W_S:
1245       case FTINT_W_D:
1246       case FTINT_L_S:
1247       case FTINT_L_D:
1248       case FFINT_S_W:
1249       case FFINT_S_L:
1250       case FFINT_D_W:
1251       case FFINT_D_L:
1252       case FRINT_S:
1253       case FRINT_D:
1254       case MOVFR2CF:
1255       case MOVCF2FR:
1256       case MOVGR2CF:
1257       case MOVCF2GR:
1258       case FRECIP_S:
1259       case FRECIP_D:
1260       case FRSQRT_S:
1261       case FRSQRT_D:
1262       case FCLASS_S:
1263       case FCLASS_D:
1264       case FLOGB_S:
1265       case FLOGB_D:
1266       case CLO_W:
1267       case CTO_W:
1268       case CLO_D:
1269       case CTO_D:
1270         kType = kOp22Type;
1271         break;
1272       default:
1273         kType = kUnsupported;
1274     }
1275   }
1276 
1277   return kType;
1278 }
1279 
1280 // -----------------------------------------------------------------------------
1281 // Instructions.
1282 
1283 template <class P>
IsTrap()1284 bool InstructionGetters<P>::IsTrap() const {
1285   return true;
1286 }
1287 
1288 }  // namespace internal
1289 }  // namespace v8
1290 
1291 #endif  // V8_CODEGEN_LOONG64_CONSTANTS_LOONG64_H_
1292