v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
constants-loong64.h
Go to the documentation of this file.
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"
11#include "src/common/globals.h"
12
13// Get the standard printf format macros for C99 stdint types.
14#ifndef __STDC_FORMAT_MACROS
15#define __STDC_FORMAT_MACROS
16#endif
17#include <inttypes.h>
18
19// Defines constants and accessor classes to assemble, disassemble and
20// simulate LOONG64 instructions.
21
22namespace v8 {
23namespace internal {
24
25constexpr size_t kMaxPCRelativeCodeRangeInMB = 128;
26
27// -----------------------------------------------------------------------------
28// Registers and FPURegisters.
29
30// Number of general purpose registers.
31const int kNumRegisters = 32;
32const int kInvalidRegister = -1;
33
34// Number of registers with pc.
35const int kNumSimuRegisters = 33;
36
37// In the simulator, the PC register is simulated as the 33th register.
38const int kPCRegister = 32;
39
40// Number of floating point registers.
41const int kNumFPURegisters = 32;
42const int kInvalidFPURegister = -1;
43
44// FPU control registers.
45const int kFCSRRegister = 0;
47const uint32_t kFPUInvalidResult = static_cast<uint32_t>(1u << 31) - 1;
48const int32_t kFPUInvalidResultNegative = static_cast<int32_t>(1u << 31);
49const uint64_t kFPU64InvalidResult =
50 static_cast<uint64_t>(static_cast<uint64_t>(1) << 63) - 1;
52 static_cast<int64_t>(static_cast<uint64_t>(1) << 63);
53
54// FCSR constants.
55const uint32_t kFCSRInexactCauseBit = 24;
56const uint32_t kFCSRUnderflowCauseBit = 25;
57const uint32_t kFCSROverflowCauseBit = 26;
58const uint32_t kFCSRDivideByZeroCauseBit = 27;
59const uint32_t kFCSRInvalidOpCauseBit = 28;
60
66
67const uint32_t kFCSRCauseMask =
70
72
73// Actual value of root register is offset from the root array's start
74// to take advantage of negative displacement values.
75constexpr int kRootRegisterBias = 256;
76
77// Helper functions for converting between register numbers and names.
78class 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.
100class 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.
122using Instr = int32_t;
123
124// Special Software Interrupt codes when used in the presence of the LOONG64
125// simulator.
127 // Transition to C code.
128 call_rt_redirected = 0x7fff
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.
138const uint32_t kMaxWatchpointCode = 31;
139const uint32_t kMaxStopCode = 127;
140static_assert(kMaxWatchpointCode < kMaxStopCode);
141
142// ----- Fields offset and length.
143const int kRjShift = 5;
144const int kRjBits = 5;
145const int kRkShift = 10;
146const int kRkBits = 5;
147const int kRdShift = 0;
148const int kRdBits = 5;
149const int kSaShift = 15;
150const int kSa2Bits = 2;
151const int kSa3Bits = 3;
152const int kCdShift = 0;
153const int kCdBits = 3;
154const int kCjShift = 5;
155const int kCjBits = 3;
156const int kCodeShift = 0;
157const int kCodeBits = 15;
158const int kCondShift = 15;
159const int kCondBits = 5;
160const int kUi5Shift = 10;
161const int kUi5Bits = 5;
162const int kUi6Shift = 10;
163const int kUi6Bits = 6;
164const int kUi12Shift = 10;
165const int kUi12Bits = 12;
166const int kSi12Shift = 10;
167const int kSi12Bits = 12;
168const int kSi14Shift = 10;
169const int kSi14Bits = 14;
170const int kSi16Shift = 10;
171const int kSi16Bits = 16;
172const int kSi20Shift = 5;
173const int kSi20Bits = 20;
174const int kMsbwShift = 16;
175const int kMsbwBits = 5;
176const int kLsbwShift = 10;
177const int kLsbwBits = 5;
178const int kMsbdShift = 16;
179const int kMsbdBits = 6;
180const int kLsbdShift = 10;
181const int kLsbdBits = 6;
182const int kFdShift = 0;
183const int kFdBits = 5;
184const int kFjShift = 5;
185const int kFjBits = 5;
186const int kFkShift = 10;
187const int kFkBits = 5;
188const int kFaShift = 15;
189const int kFaBits = 5;
190const int kCaShift = 15;
191const int kCaBits = 3;
192const int kHint15Shift = 0;
193const int kHint15Bits = 15;
194const int kHint5Shift = 0;
195const int kHint5Bits = 5;
196const int kOffsLowShift = 10;
197const int kOffsLowBits = 16;
198const int kOffs26HighShift = 0;
199const int kOffs26HighBits = 10;
200const int kOffs21HighShift = 0;
201const int kOffs21HighBits = 5;
202const int kImm12Shift = 0;
203const int kImm12Bits = 12;
204const int kImm16Shift = 0;
205const int kImm16Bits = 16;
206const int kImm26Shift = 0;
207const int kImm26Bits = 26;
208const int kImm28Shift = 0;
209const int kImm28Bits = 28;
210const int kImm32Shift = 0;
211const int kImm32Bits = 32;
212
213// ----- Miscellaneous useful masks.
214// Instruction bit masks.
215const int kRjFieldMask = ((1 << kRjBits) - 1) << kRjShift;
216const int kRkFieldMask = ((1 << kRkBits) - 1) << kRkShift;
217const int kRdFieldMask = ((1 << kRdBits) - 1) << kRdShift;
218const int kSa2FieldMask = ((1 << kSa2Bits) - 1) << kSaShift;
219const int kSa3FieldMask = ((1 << kSa3Bits) - 1) << kSaShift;
220// Misc masks.
221const int kHiMaskOf32 = 0xffff << 16; // Only to be used with 32-bit values
222const int kLoMaskOf32 = 0xffff;
223const int kSignMaskOf32 = 0x80000000; // Only to be used with 32-bit values
224const int64_t kTop16MaskOf64 = (int64_t)0xffff << 48;
225const int64_t kHigher16MaskOf64 = (int64_t)0xffff << 32;
226const int64_t kUpper16MaskOf64 = (int64_t)0xffff << 16;
227
228const int kImm12Mask = ((1 << kImm12Bits) - 1) << kImm12Shift;
229const int kImm16Mask = ((1 << kImm16Bits) - 1) << kImm16Shift;
230const int kImm26Mask = ((1 << kImm26Bits) - 1) << kImm26Shift;
231const int kImm28Mask = ((1 << kImm28Bits) - 1) << kImm28Shift;
232
233// ----- LOONG64 Opcodes and Function Fields.
234enum 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
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,
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
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.
537enum Condition : int {
538 overflow = 0,
539 no_overflow = 1,
540 Uless = 2,
544 equal = 6,
545 not_equal = 7, // Unordered or Not Equal.
546 negative = 8,
547 positive = 9,
548 parity_even = 10,
549 parity_odd = 11,
550 less = 12,
551 greater_equal = 13,
552 less_equal = 14,
553 greater = 15,
554 ueq = 16, // Unordered or Equal.
555 ogl = 17, // Ordered and Not Equal.
557
558 // Aliases.
559 carry = Uless,
561 zero = equal,
562 eq = equal,
564 ne = not_equal,
566 sign = negative,
568 mi = negative,
569 pl = positive,
570 hi = Ugreater,
571 ls = Uless_equal,
573 lt = less,
574 gt = greater,
575 le = less_equal,
577 lo = Uless,
578 al = cc_always,
583
584 // Unified cross-platform condition names/aliases.
585 kEqual = equal,
587 kLessThan = less,
597 kZero = equal,
599};
600
601// Returns the equivalent of !cc.
603 DCHECK(cc != cc_always);
604 return static_cast<Condition>(cc ^ 1);
605}
606
608 DCHECK(cc != cc_always);
609 switch (cc) {
610 case ult:
611 return ge;
612 case ugt:
613 return le;
614 case uge:
615 return lt;
616 case ule:
617 return gt;
618 case lt:
619 return uge;
620 case gt:
621 return ule;
622 case ge:
623 return ult;
624 case le:
625 return ugt;
626 case eq:
627 return ne;
628 case ne:
629 return eq;
630 case ueq:
631 return ogl;
632 case ogl:
633 return ueq;
634 default:
635 return cc;
636 }
637}
638
639// ----- Coprocessor conditions.
642
643 CAF = 0x00, // False.
644 SAF = 0x01, // False.
645 CLT = 0x02, // Less Than quiet
646 // SLT = 0x03, // Less Than signaling
647 CEQ = 0x04,
648 SEQ = 0x05,
649 CLE = 0x06,
650 SLE = 0x07,
651 CUN = 0x08,
652 SUN = 0x09,
653 CULT = 0x0a,
654 SULT = 0x0b,
655 CUEQ = 0x0c,
656 SUEQ = 0x0d,
657 CULE = 0x0e,
658 SULE = 0x0f,
659 CNE = 0x10,
660 SNE = 0x11,
661 COR = 0x14,
662 SOR = 0x15,
663 CUNE = 0x18,
664 SUNE = 0x19,
665};
666
667const uint32_t kFPURoundingModeShift = 8;
669
670// FPU rounding modes.
672 RN = 0b00 << kFPURoundingModeShift, // Round to Nearest.
673 RZ = 0b01 << kFPURoundingModeShift, // Round towards zero.
674 RP = 0b10 << kFPURoundingModeShift, // Round towards Plus Infinity.
675 RM = 0b11 << kFPURoundingModeShift, // Round towards Minus Infinity.
676
677 // Aliases.
682
686 mode_trunc = RZ
688
693
694enum class MaxMinKind : int { kMin = 0, kMax = 1 };
695
696// -----------------------------------------------------------------------------
697// Hints.
698
699// Branch hints are not used on the LOONG64. They are defined so that they can
700// appear in shared function signatures, but will be ignored in LOONG64
701// implementations.
702enum Hint { no_hint = 0 };
703
704inline Hint NegateHint(Hint hint) { return no_hint; }
705
706// -----------------------------------------------------------------------------
707// Specific instructions, constants, and masks.
708// These constants are declared in assembler-loong64.cc, as they use named
709// registers and other constants.
710
711// Break 0xfffff, reserved for redirected real time call.
713 static_cast<uint32_t>(BREAK) | call_rt_redirected;
714// A nop instruction. (Encoding of addi_w 0 0 0).
716
717constexpr uint8_t kInstrSize = 4;
718constexpr uint8_t kInstrSizeLog2 = 2;
719
720class InstructionBase {
721 public:
733
734 // Get the raw instruction bits.
735 inline Instr InstructionBits() const {
736 return *reinterpret_cast<const Instr*>(this);
737 }
738
739 // Set the raw instruction bits to value.
741 Instr new_instr, WritableJitAllocation* jit_allocation = nullptr);
742
743 // Read one particular bit out of the instruction bits.
744 inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
745
746 // Read a bit field out of the instruction bits.
747 inline int Bits(int hi, int lo) const {
748 return (InstructionBits() >> lo) & ((2U << (hi - lo)) - 1);
749 }
750
751 // Safe to call within InstructionType().
752 inline int RjFieldRawNoAssert() const {
753 return InstructionBits() & kRjFieldMask;
754 }
755
756 // Get the encoding type of the instruction.
757 inline Type InstructionType() const;
758
759 protected:
761};
762
763template <class T>
764class InstructionGetters : public T {
765 public:
766 inline int RjValue() const {
767 return this->Bits(kRjShift + kRjBits - 1, kRjShift);
768 }
769
770 inline int RkValue() const {
771 return this->Bits(kRkShift + kRkBits - 1, kRkShift);
772 }
773
774 inline int RdValue() const {
775 return this->Bits(kRdShift + kRdBits - 1, kRdShift);
776 }
777
778 inline int Sa2Value() const {
779 return this->Bits(kSaShift + kSa2Bits - 1, kSaShift);
780 }
781
782 inline int Sa3Value() const {
783 return this->Bits(kSaShift + kSa3Bits - 1, kSaShift);
784 }
785
786 inline int Ui5Value() const {
787 return this->Bits(kUi5Shift + kUi5Bits - 1, kUi5Shift);
788 }
789
790 inline int Ui6Value() const {
791 return this->Bits(kUi6Shift + kUi6Bits - 1, kUi6Shift);
792 }
793
794 inline int Ui12Value() const {
795 return this->Bits(kUi12Shift + kUi12Bits - 1, kUi12Shift);
796 }
797
798 inline int LsbwValue() const {
799 return this->Bits(kLsbwShift + kLsbwBits - 1, kLsbwShift);
800 }
801
802 inline int MsbwValue() const {
803 return this->Bits(kMsbwShift + kMsbwBits - 1, kMsbwShift);
804 }
805
806 inline int LsbdValue() const {
807 return this->Bits(kLsbdShift + kLsbdBits - 1, kLsbdShift);
808 }
809
810 inline int MsbdValue() const {
811 return this->Bits(kMsbdShift + kMsbdBits - 1, kMsbdShift);
812 }
813
814 inline int CondValue() const {
815 return this->Bits(kCondShift + kCondBits - 1, kCondShift);
816 }
817
818 inline int Si12Value() const {
819 return this->Bits(kSi12Shift + kSi12Bits - 1, kSi12Shift);
820 }
821
822 inline int Si14Value() const {
823 return this->Bits(kSi14Shift + kSi14Bits - 1, kSi14Shift);
824 }
825
826 inline int Si16Value() const {
827 return this->Bits(kSi16Shift + kSi16Bits - 1, kSi16Shift);
828 }
829
830 inline int Si20Value() const {
831 return this->Bits(kSi20Shift + kSi20Bits - 1, kSi20Shift);
832 }
833
834 inline int FdValue() const {
835 return this->Bits(kFdShift + kFdBits - 1, kFdShift);
836 }
837
838 inline int FaValue() const {
839 return this->Bits(kFaShift + kFaBits - 1, kFaShift);
840 }
841
842 inline int FjValue() const {
843 return this->Bits(kFjShift + kFjBits - 1, kFjShift);
844 }
845
846 inline int FkValue() const {
847 return this->Bits(kFkShift + kFkBits - 1, kFkShift);
848 }
849
850 inline int CjValue() const {
851 return this->Bits(kCjShift + kCjBits - 1, kCjShift);
852 }
853
854 inline int CdValue() const {
855 return this->Bits(kCdShift + kCdBits - 1, kCdShift);
856 }
857
858 inline int CaValue() const {
859 return this->Bits(kCaShift + kCaBits - 1, kCaShift);
860 }
861
862 inline int CodeValue() const {
863 return this->Bits(kCodeShift + kCodeBits - 1, kCodeShift);
864 }
865
866 inline int Hint5Value() const {
867 return this->Bits(kHint5Shift + kHint5Bits - 1, kHint5Shift);
868 }
869
870 inline int Hint15Value() const {
871 return this->Bits(kHint15Shift + kHint15Bits - 1, kHint15Shift);
872 }
873
874 inline int Offs16Value() const {
875 return this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
876 }
877
878 inline int Offs21Value() const {
879 int low = this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
880 int high =
882 return ((high << kOffsLowBits) + low);
883 }
884
885 inline int Offs26Value() const {
886 int low = this->Bits(kOffsLowShift + kOffsLowBits - 1, kOffsLowShift);
887 int high =
889 return ((high << kOffsLowBits) + low);
890 }
891
892 inline int RjFieldRaw() const {
893 return this->InstructionBits() & kRjFieldMask;
894 }
895
896 inline int RkFieldRaw() const {
897 return this->InstructionBits() & kRkFieldMask;
898 }
899
900 inline int RdFieldRaw() const {
901 return this->InstructionBits() & kRdFieldMask;
902 }
903
904 inline int32_t ImmValue(int bits) const { return this->Bits(bits - 1, 0); }
905
906 /*TODO*/
907 inline int32_t Imm12Value() const { abort(); }
908
909 inline int32_t Imm14Value() const { abort(); }
910
911 inline int32_t Imm16Value() const { abort(); }
912
913 // Say if the instruction is a break.
914 bool IsTrap() const;
915};
916
917class Instruction : public InstructionGetters<InstructionBase> {
918 public:
919 // Instructions are read of out a code stream. The only way to get a
920 // reference to an instruction is to convert a pointer. There is no way
921 // to allocate or create instances of class Instruction.
922 // Use the At(pc) function to create references to Instruction.
923 static Instruction* At(uint8_t* pc) {
924 return reinterpret_cast<Instruction*>(pc);
925 }
926
927 private:
928 // We need to prevent the creation of instances of class Instruction.
930};
931
932// -----------------------------------------------------------------------------
933// LOONG64 assembly various constants.
934
935const int kInvalidStackOffset = -1;
936
937static const int kNegOffset = 0x00008000;
938
941
942 // Check for kOp6Type
943 switch (Bits(31, 26) << 26) {
944 case ADDU16I_D:
945 case BEQZ:
946 case BNEZ:
947 case BCZ:
948 case JIRL:
949 case B:
950 case BL:
951 case BEQ:
952 case BNE:
953 case BLT:
954 case BGE:
955 case BLTU:
956 case BGEU:
957 kType = kOp6Type;
958 break;
959 default:
960 kType = kUnsupported;
961 }
962
963 if (kType == kUnsupported) {
964 // Check for kOp7Type
965 switch (Bits(31, 25) << 25) {
966 case LU12I_W:
967 case LU32I_D:
968 case PCADDI:
969 case PCALAU12I:
970 case PCADDU12I:
971 case PCADDU18I:
972 kType = kOp7Type;
973 break;
974 default:
975 kType = kUnsupported;
976 }
977 }
978
979 if (kType == kUnsupported) {
980 // Check for kOp8Type
981 switch (Bits(31, 24) << 24) {
982 case LDPTR_W:
983 case STPTR_W:
984 case LDPTR_D:
985 case STPTR_D:
986 case LL_W:
987 case SC_W:
988 case LL_D:
989 case SC_D:
990 kType = kOp8Type;
991 break;
992 default:
993 kType = kUnsupported;
994 }
995 }
996
997 if (kType == kUnsupported) {
998 // Check for kOp10Type
999 switch (Bits(31, 22) << 22) {
1000 case BSTR_W: {
1001 // If Bit(21) = 0, then the Opcode is not BSTR_W.
1002 if (Bit(21) == 0)
1003 kType = kUnsupported;
1004 else
1005 kType = kOp10Type;
1006 break;
1007 }
1008 case BSTRINS_D:
1009 case BSTRPICK_D:
1010 case SLTI:
1011 case SLTUI:
1012 case ADDI_W:
1013 case ADDI_D:
1014 case LU52I_D:
1015 case ANDI:
1016 case ORI:
1017 case XORI:
1018 case LD_B:
1019 case LD_H:
1020 case LD_W:
1021 case LD_D:
1022 case ST_B:
1023 case ST_H:
1024 case ST_W:
1025 case ST_D:
1026 case LD_BU:
1027 case LD_HU:
1028 case LD_WU:
1029 case FLD_S:
1030 case FST_S:
1031 case FLD_D:
1032 case FST_D:
1033 kType = kOp10Type;
1034 break;
1035 default:
1036 kType = kUnsupported;
1037 }
1038 }
1039
1040 if (kType == kUnsupported) {
1041 // Check for kOp12Type
1042 switch (Bits(31, 20) << 20) {
1043 case FMADD_S:
1044 case FMADD_D:
1045 case FMSUB_S:
1046 case FMSUB_D:
1047 case FNMADD_S:
1048 case FNMADD_D:
1049 case FNMSUB_S:
1050 case FNMSUB_D:
1051 case FCMP_COND_S:
1052 case FCMP_COND_D:
1053 case FSEL:
1054 kType = kOp12Type;
1055 break;
1056 default:
1057 kType = kUnsupported;
1058 }
1059 }
1060
1061 if (kType == kUnsupported) {
1062 // Check for kOp14Type
1063 switch (Bits(31, 18) << 18) {
1064 case ALSL:
1065 case BYTEPICK_W:
1066 case BYTEPICK_D:
1067 case ALSL_D:
1068 case SLLI:
1069 case SRLI:
1070 case SRAI:
1071 case ROTRI:
1072 kType = kOp14Type;
1073 break;
1074 default:
1075 kType = kUnsupported;
1076 }
1077 }
1078
1079 if (kType == kUnsupported) {
1080 // Check for kOp17Type
1081 switch (Bits(31, 15) << 15) {
1082 case ADD_W:
1083 case ADD_D:
1084 case SUB_W:
1085 case SUB_D:
1086 case SLT:
1087 case SLTU:
1088 case MASKEQZ:
1089 case MASKNEZ:
1090 case NOR:
1091 case AND:
1092 case OR:
1093 case XOR:
1094 case ORN:
1095 case ANDN:
1096 case SLL_W:
1097 case SRL_W:
1098 case SRA_W:
1099 case SLL_D:
1100 case SRL_D:
1101 case SRA_D:
1102 case ROTR_D:
1103 case ROTR_W:
1104 case MUL_W:
1105 case MULH_W:
1106 case MULH_WU:
1107 case MUL_D:
1108 case MULH_D:
1109 case MULH_DU:
1110 case MULW_D_W:
1111 case MULW_D_WU:
1112 case DIV_W:
1113 case MOD_W:
1114 case DIV_WU:
1115 case MOD_WU:
1116 case DIV_D:
1117 case MOD_D:
1118 case DIV_DU:
1119 case MOD_DU:
1120 case BREAK:
1121 case FADD_S:
1122 case FADD_D:
1123 case FSUB_S:
1124 case FSUB_D:
1125 case FMUL_S:
1126 case FMUL_D:
1127 case FDIV_S:
1128 case FDIV_D:
1129 case FMAX_S:
1130 case FMAX_D:
1131 case FMIN_S:
1132 case FMIN_D:
1133 case FMAXA_S:
1134 case FMAXA_D:
1135 case FMINA_S:
1136 case FMINA_D:
1137 case LDX_B:
1138 case LDX_H:
1139 case LDX_W:
1140 case LDX_D:
1141 case STX_B:
1142 case STX_H:
1143 case STX_W:
1144 case STX_D:
1145 case LDX_BU:
1146 case LDX_HU:
1147 case LDX_WU:
1148 case FLDX_S:
1149 case FLDX_D:
1150 case FSTX_S:
1151 case FSTX_D:
1152 case AMSWAP_W:
1153 case AMSWAP_D:
1154 case AMADD_W:
1155 case AMADD_D:
1156 case AMAND_W:
1157 case AMAND_D:
1158 case AMOR_W:
1159 case AMOR_D:
1160 case AMXOR_W:
1161 case AMXOR_D:
1162 case AMMAX_W:
1163 case AMMAX_D:
1164 case AMMIN_W:
1165 case AMMIN_D:
1166 case AMMAX_WU:
1167 case AMMAX_DU:
1168 case AMMIN_WU:
1169 case AMMIN_DU:
1170 case AMSWAP_DB_W:
1171 case AMSWAP_DB_D:
1172 case AMADD_DB_W:
1173 case AMADD_DB_D:
1174 case AMAND_DB_W:
1175 case AMAND_DB_D:
1176 case AMOR_DB_W:
1177 case AMOR_DB_D:
1178 case AMXOR_DB_W:
1179 case AMXOR_DB_D:
1180 case AMMAX_DB_W:
1181 case AMMAX_DB_D:
1182 case AMMIN_DB_W:
1183 case AMMIN_DB_D:
1184 case AMMAX_DB_WU:
1185 case AMMAX_DB_DU:
1186 case AMMIN_DB_WU:
1187 case AMMIN_DB_DU:
1188 case DBAR:
1189 case IBAR:
1190 case FSCALEB_S:
1191 case FSCALEB_D:
1192 case FCOPYSIGN_S:
1193 case FCOPYSIGN_D:
1194 kType = kOp17Type;
1195 break;
1196 default:
1197 kType = kUnsupported;
1198 }
1199 }
1200
1201 if (kType == kUnsupported) {
1202 // Check for kOp22Type
1203 switch (Bits(31, 10) << 10) {
1204 case CLZ_W:
1205 case CTZ_W:
1206 case CLZ_D:
1207 case CTZ_D:
1208 case REVB_2H:
1209 case REVB_4H:
1210 case REVB_2W:
1211 case REVB_D:
1212 case REVH_2W:
1213 case REVH_D:
1214 case BITREV_4B:
1215 case BITREV_8B:
1216 case BITREV_W:
1217 case BITREV_D:
1218 case EXT_W_B:
1219 case EXT_W_H:
1220 case FABS_S:
1221 case FABS_D:
1222 case FNEG_S:
1223 case FNEG_D:
1224 case FSQRT_S:
1225 case FSQRT_D:
1226 case FMOV_S:
1227 case FMOV_D:
1228 case MOVGR2FR_W:
1229 case MOVGR2FR_D:
1230 case MOVGR2FRH_W:
1231 case MOVFR2GR_S:
1232 case MOVFR2GR_D:
1233 case MOVFRH2GR_S:
1234 case MOVGR2FCSR:
1235 case MOVFCSR2GR:
1236 case FCVT_S_D:
1237 case FCVT_D_S:
1238 case FTINTRM_W_S:
1239 case FTINTRM_W_D:
1240 case FTINTRM_L_S:
1241 case FTINTRM_L_D:
1242 case FTINTRP_W_S:
1243 case FTINTRP_W_D:
1244 case FTINTRP_L_S:
1245 case FTINTRP_L_D:
1246 case FTINTRZ_W_S:
1247 case FTINTRZ_W_D:
1248 case FTINTRZ_L_S:
1249 case FTINTRZ_L_D:
1250 case FTINTRNE_W_S:
1251 case FTINTRNE_W_D:
1252 case FTINTRNE_L_S:
1253 case FTINTRNE_L_D:
1254 case FTINT_W_S:
1255 case FTINT_W_D:
1256 case FTINT_L_S:
1257 case FTINT_L_D:
1258 case FFINT_S_W:
1259 case FFINT_S_L:
1260 case FFINT_D_W:
1261 case FFINT_D_L:
1262 case FRINT_S:
1263 case FRINT_D:
1264 case MOVFR2CF:
1265 case MOVCF2FR:
1266 case MOVGR2CF:
1267 case MOVCF2GR:
1268 case FRECIP_S:
1269 case FRECIP_D:
1270 case FRSQRT_S:
1271 case FRSQRT_D:
1272 case FCLASS_S:
1273 case FCLASS_D:
1274 case FLOGB_S:
1275 case FLOGB_D:
1276 case CLO_W:
1277 case CTO_W:
1278 case CLO_D:
1279 case CTO_D:
1280 kType = kOp22Type;
1281 break;
1282 default:
1283 kType = kUnsupported;
1284 }
1285 }
1286
1287 return kType;
1288}
1289
1290// -----------------------------------------------------------------------------
1291// Instructions.
1292
1293template <class P>
1295 if ((this->Bits(31, 15) << 15) == BREAK) return true;
1296 return false;
1297}
1298
1299} // namespace internal
1300} // namespace v8
1301
1302#endif // V8_CODEGEN_LOONG64_CONSTANTS_LOONG64_H_
static const RegisterAlias aliases_[]
static const char * names_[kNumFPURegisters]
static const char * Name(int reg)
int Bits(int hi, int lo) const
V8_EXPORT_PRIVATE void SetInstructionBits(Instr new_instr, WritableJitAllocation *jit_allocation=nullptr)
static Instruction * At(uint8_t *pc)
DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction)
static const char * Name(int reg)
static int Number(const char *name)
static const int64_t kMaxValue
static const RegisterAlias aliases_[]
static const char * names_[kNumRegisters]
static const int64_t kMinValue
LiftoffRegister reg
Hint NegateHint(Hint ignored)
constexpr VFPRoundingMode kRoundToNearest
constexpr UnconditionalBranchOp BL
const Instr nopInstr
constexpr VFPRoundingMode kRoundToMinusInf
constexpr Opcode AND
const uint32_t kFCSRInexactCauseMask
const int kInvalidFPUControlRegister
const int kFCSRRegister
const int kSa3FieldMask
const int kImm12Shift
const uint32_t kFCSRDivideByZeroCauseBit
const uint32_t kFCSRDivideByZeroCauseMask
const int kImm26Shift
constexpr VFPRoundingMode RP
constexpr int kPCRegister
@ kDontCheckForInexactConversion
const int kSignMaskOf32
const uint32_t kFCSRInvalidOpCauseMask
const int kHiMaskOf32
const Instr rtCallRedirInstr
constexpr uint32_t kMaxStopCode
const uint32_t kMaxWatchpointCode
const int kInvalidStackOffset
static const int kNegOffset
const int64_t kUpper16MaskOf64
constexpr int B
const int kOffs26HighBits
const int kNumFPURegisters
constexpr int kImm16Mask
const int kInvalidFPURegister
Union< Smi, HeapNumber > Number
Definition globals.h:1181
const int kOffs26HighShift
constexpr VFPRoundingMode RM
constexpr uint8_t kInstrSizeLog2
const int kNumSimuRegisters
const int kImm32Shift
const int kOffs21HighShift
const uint32_t kFPURoundingModeShift
constexpr VFPRoundingMode kRoundToPlusInf
const int kRkFieldMask
const int kInvalidRegister
const int64_t kFPU64InvalidResultNegative
const uint32_t kFCSRInexactCauseBit
constexpr LogicalOp ORN
const int32_t kFPUInvalidResultNegative
Condition NegateCondition(Condition cond)
const int kHint15Shift
const uint32_t kFCSROverflowCauseMask
constexpr VFPRoundingMode RZ
constexpr size_t kMaxPCRelativeCodeRangeInMB
const int kSa2FieldMask
const int kImm28Shift
const uint32_t kFCSRUnderflowCauseBit
const uint64_t kFPU64InvalidResult
const uint32_t kFPURoundingModeMask
const uint32_t kFCSRUnderflowCauseMask
const int kOffsLowBits
const int kHint5Shift
const int kOffsLowShift
constexpr VFPRoundingMode kRoundToZero
const int64_t kHigher16MaskOf64
constexpr VFPRoundingMode RN
const uint32_t kFPUInvalidResult
constexpr uint8_t kInstrSize
const int kRjFieldMask
const int kImm16Shift
constexpr int kRootRegisterBias
const int kHint15Bits
const int kLoMaskOf32
const int64_t kTop16MaskOf64
const int kRdFieldMask
const uint32_t kFCSROverflowCauseBit
const uint32_t kFCSRInvalidOpCauseBit
const uint32_t kFCSRExceptionCauseMask
Condition NegateFpuCondition(Condition cc)
const int kOffs21HighBits
constexpr int kNumRegisters
const uint32_t kFCSRCauseMask
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460