mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-26 15:01:31 +00:00
Merge pull request #7406 from odin-lang/bill/rexcode-riscv-clobber
Inline `asm` RISC-V Support
This commit is contained in:
47
core/rexcode/isa/riscv/clobber_types.odin
Normal file
47
core/rexcode/isa/riscv/clobber_types.odin
Normal file
@@ -0,0 +1,47 @@
|
||||
package rexcode_riscv
|
||||
|
||||
// Operand slots (indices into the Encoding operand list) that are read/written.
|
||||
// Max 4 operands (R4-type FMA: rd, rs1, rs2, rs3).
|
||||
Operand_Set :: distinct bit_set[0..<4; u8]
|
||||
|
||||
FFlags :: distinct bit_set[FFlag; u8]
|
||||
// fcsr accrued exception flags. This is the ONLY flag state in RISC-V — there
|
||||
// are no integer condition codes, so there is no EFLAGS-style triad here.
|
||||
FFlag :: enum u8 {
|
||||
NV, // invalid operation
|
||||
DZ, // divide by zero
|
||||
OF, // overflow
|
||||
UF, // underflow
|
||||
NX, // inexact
|
||||
}
|
||||
|
||||
Clobber_Regs :: distinct bit_set[Clobber_Reg; u8]
|
||||
// Implicitly-touched registers that are NOT distinct operands. RISC-V's base
|
||||
// ISA has almost none of these (unlike x86's RAX/RDX/RSP-heavy encodings) —
|
||||
// only the compressed link/stack forms.
|
||||
Clobber_Reg :: enum u8 {
|
||||
RA, // x1, implicit link on C.JAL / C.JALR
|
||||
SP, // x2, implicit base on the *SP compressed forms
|
||||
}
|
||||
|
||||
Side_Effects :: distinct bit_set[Side_Effect; u8]
|
||||
Side_Effect :: enum u8 {
|
||||
CONTROL, // writes pc: branches, jumps, and trap redirects
|
||||
TRAP, // synchronous environment trap (ECALL / EBREAK)
|
||||
FENCE, // explicit memory-ordering barrier (FENCE)
|
||||
IFENCE, // instruction-fetch synchronization (FENCE.I)
|
||||
ATOMIC, // indivisible memory RMW (AMO*, and the LR/SC pair)
|
||||
RESERVATION, // sets or tests an LR/SC reservation
|
||||
}
|
||||
|
||||
Clobber :: struct {
|
||||
written: Operand_Set, // operand slots whose register/CSR is written
|
||||
read: Operand_Set, // operand slots whose register/CSR/mem-base is read
|
||||
implicit_wr: Clobber_Regs, // implicit reg writes (ra on C.JAL/C.JALR)
|
||||
implicit_rd: Clobber_Regs, // implicit reg reads (sp on the *SP forms)
|
||||
fflags_wr: FFlags, // accrued exception flags this op may raise
|
||||
reads_frm: bool, // consumes the dynamic rounding mode from fcsr
|
||||
writes_mem: bool,
|
||||
reads_mem: bool,
|
||||
side_effects: Side_Effects,
|
||||
}
|
||||
@@ -455,6 +455,10 @@ resolve_relocation_inline :: #force_inline proc(
|
||||
return true
|
||||
}
|
||||
|
||||
is_implicit_op_inline :: #force_inline proc "contextless" (op: Operand_Type) -> bool {
|
||||
return op == .GPR_SP
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Scatter / gather helpers for B-type and J-type immediates
|
||||
// =============================================================================
|
||||
|
||||
@@ -40,7 +40,7 @@ LABEL_UNDEFINED :: isa.LABEL_UNDEFINED
|
||||
Label_Map :: isa.Label_Map
|
||||
|
||||
// Extension this entry belongs to (metadata, not used by the matcher).
|
||||
Feature :: enum u8 {
|
||||
Feature :: enum u16 {
|
||||
I, // RV32I / RV64I base integer
|
||||
M, // multiply / divide
|
||||
A, // atomics
|
||||
@@ -49,14 +49,22 @@ Feature :: enum u8 {
|
||||
ZICSR, // CSR access (CSRRW/S/C + immediate forms)
|
||||
ZIFENCEI, // FENCE.I (instruction-fetch fence)
|
||||
C, // 16-bit compressed instructions
|
||||
ZBA, // address-generation bit-manip
|
||||
ZBB, // basic bit-manip
|
||||
ZBC, // carry-less multiply
|
||||
ZBS, // single-bit bit-manip
|
||||
ZICOND, // conditional zeroing
|
||||
ZFH, // half-precision (binary16) FP
|
||||
PRIV, // privileged trap-return / TLB maintenance
|
||||
}
|
||||
|
||||
Encoding_Flags :: bit_field u8 {
|
||||
rv32_only: bool | 1, // RV32 base only
|
||||
rv64_only: bool | 1, // RV64 base only (e.g. LD/SD/ADDIW/...)
|
||||
branch: bool | 1, // changes PC
|
||||
fp_round: bool | 1, // funct3 doubles as FP rounding-mode field
|
||||
_: u8 | 4,
|
||||
rv32_only: bool | 1, // RV32 base only
|
||||
rv64_only: bool | 1, // RV64 base only (e.g. LD/SD/ADDIW/...)
|
||||
branch: bool | 1, // changes PC
|
||||
fp_round: bool | 1, // funct3 doubles as FP rounding-mode field
|
||||
explicit_count: u8 | 3,
|
||||
has_implicit: bool | 1,
|
||||
}
|
||||
|
||||
// What the user passes in.
|
||||
@@ -149,10 +157,10 @@ Encoding :: struct #packed {
|
||||
enc: [4]Operand_Encoding, // 4
|
||||
bits: u32, // 4 -- static bit pattern
|
||||
mask: u32, // 4 -- which bits are static
|
||||
feature: Feature, // 1
|
||||
feature: Feature, // 2
|
||||
flags: Encoding_Flags, // 1
|
||||
}
|
||||
#assert(size_of(Encoding) == 20)
|
||||
#assert(size_of(Encoding) == 21)
|
||||
|
||||
// inst_size_from_bits returns 2 for compressed (RVC) instructions, 4 for the
|
||||
// standard 32-bit base ISA. RISC-V uses a length-encoding convention where
|
||||
|
||||
@@ -139,4 +139,89 @@ Mnemonic :: enum u16 {
|
||||
C_FLDSP, C_FSDSP,
|
||||
C_JR, C_JALR, C_MV, C_ADD,
|
||||
C_FLWSP, C_FSWSP,
|
||||
|
||||
|
||||
SH1ADD,
|
||||
SH2ADD,
|
||||
SH3ADD,
|
||||
ADD_UW,
|
||||
SH1ADD_UW,
|
||||
SH2ADD_UW,
|
||||
SH3ADD_UW,
|
||||
SLLI_UW,
|
||||
ANDN,
|
||||
ORN,
|
||||
XNOR,
|
||||
CLZ,
|
||||
CTZ,
|
||||
CPOP,
|
||||
SEXT_B,
|
||||
SEXT_H,
|
||||
ZEXT_H,
|
||||
MIN,
|
||||
MINU,
|
||||
MAX,
|
||||
MAXU,
|
||||
ROL,
|
||||
ROR,
|
||||
RORI,
|
||||
ORC_B,
|
||||
REV8,
|
||||
CLZW,
|
||||
CTZW,
|
||||
CPOPW,
|
||||
ROLW,
|
||||
RORW,
|
||||
RORIW,
|
||||
CLMUL,
|
||||
CLMULH,
|
||||
CLMULR,
|
||||
BCLR,
|
||||
BCLRI,
|
||||
BEXT,
|
||||
BEXTI,
|
||||
BINV,
|
||||
BINVI,
|
||||
BSET,
|
||||
BSETI,
|
||||
CZERO_EQZ,
|
||||
CZERO_NEZ,
|
||||
FLH,
|
||||
FSH,
|
||||
FMADD_H,
|
||||
FMSUB_H,
|
||||
FNMSUB_H,
|
||||
FNMADD_H,
|
||||
FADD_H,
|
||||
FSUB_H,
|
||||
FMUL_H,
|
||||
FDIV_H,
|
||||
FSQRT_H,
|
||||
FSGNJ_H,
|
||||
FSGNJN_H,
|
||||
FSGNJX_H,
|
||||
FMIN_H,
|
||||
FMAX_H,
|
||||
FCVT_W_H,
|
||||
FCVT_WU_H,
|
||||
FCVT_L_H,
|
||||
FCVT_LU_H,
|
||||
FCVT_H_W,
|
||||
FCVT_H_WU,
|
||||
FCVT_H_L,
|
||||
FCVT_H_LU,
|
||||
FCVT_S_H,
|
||||
FCVT_H_S,
|
||||
FCVT_D_H,
|
||||
FCVT_H_D,
|
||||
FMV_X_H,
|
||||
FMV_H_X,
|
||||
FCLASS_H,
|
||||
FEQ_H,
|
||||
FLT_H,
|
||||
FLE_H,
|
||||
MRET,
|
||||
SRET,
|
||||
WFI,
|
||||
SFENCE_VMA,
|
||||
}
|
||||
|
||||
171
core/rexcode/isa/riscv/pseudo_aliases.odin
Normal file
171
core/rexcode/isa/riscv/pseudo_aliases.odin
Normal file
@@ -0,0 +1,171 @@
|
||||
package rexcode_riscv
|
||||
|
||||
// =============================================================================
|
||||
// RISC-V PSEUDO-INSTRUCTION ALIAS TABLE
|
||||
//
|
||||
// Every entry here lowers to exactly ONE real INSTRUCTION_TABLE mnemonic by
|
||||
// filling that target's operand slots. The real entry supplies the encoding
|
||||
// and the clobber set for free — a pseudo's dataflow is its target's dataflow.
|
||||
//
|
||||
// Pseudos that CANNOT be expressed this way (value-dependent expansions and a
|
||||
// couple of fixed-word HINTs) are listed as comments at the bottom; they stay
|
||||
// procedures or dedicated table rows.
|
||||
// =============================================================================
|
||||
|
||||
// How each operand slot of the target instruction is filled.
|
||||
Alias_Src :: enum u8 {
|
||||
NONE, // slot unused
|
||||
ARG0, // user's 1st operand
|
||||
ARG1, // user's 2nd operand
|
||||
ARG2, // user's 3rd operand
|
||||
X0, // hardwired zero (x0)
|
||||
X1, // link register (ra / x1)
|
||||
LIT, // the `lit` field below (immediate literal)
|
||||
CSR_LIT, // the `csr` field below (fixed 12-bit CSR address)
|
||||
}
|
||||
|
||||
Pseudo_Alias :: struct {
|
||||
target: Mnemonic, // real instruction emitted
|
||||
src: [4]Alias_Src, // how to fill target's four operand slots
|
||||
lit: i16, // immediate when a src slot is .LIT
|
||||
csr: u16, // CSR address when a src slot is .CSR_LIT
|
||||
nargs: u8, // operands the user supplies (ARG0..<ARGn)
|
||||
rv32_only: bool, // base gate (the *h counter reads)
|
||||
}
|
||||
|
||||
Pseudo_Mnemonic :: enum u16 {
|
||||
INVALID,
|
||||
// integer moves / arithmetic
|
||||
NOP, MV, NOT, NEG, NEGW, SEXT_W, ZEXT_B,
|
||||
// set-if / compare-to-zero
|
||||
SEQZ, SNEZ, SLTZ, SGTZ,
|
||||
// branch-on-zero
|
||||
BEQZ, BNEZ, BLEZ, BGEZ, BLTZ, BGTZ,
|
||||
// branch with swapped operands
|
||||
BGT, BLE, BGTU, BLEU,
|
||||
// jumps
|
||||
J, JAL_RA, JR, JALR_RA, RET,
|
||||
// generic CSR access
|
||||
CSRR, CSRW, CSRS, CSRC, CSRWI, CSRSI, CSRCI,
|
||||
// named counter reads (CSR baked in)
|
||||
RDCYCLE, RDTIME, RDINSTRET, RDCYCLEH, RDTIMEH, RDINSTRETH,
|
||||
// fcsr / frm / fflags accessors
|
||||
FRCSR, FSCSR, FRRM, FSRM, FRFLAGS, FSFLAGS, FSRMI, FSFLAGSI,
|
||||
// FP sign-injection moves
|
||||
FMV_S, FABS_S, FNEG_S,
|
||||
FMV_D, FABS_D, FNEG_D,
|
||||
FMV_H, FABS_H, FNEG_H,
|
||||
// memory ordering
|
||||
FENCE_ALL,
|
||||
}
|
||||
|
||||
@(rodata)
|
||||
PSEUDO_ALIASES := [Pseudo_Mnemonic]Pseudo_Alias{
|
||||
.INVALID = {},
|
||||
// -------------------------------------------------------------------------
|
||||
// Integer moves / arithmetic
|
||||
// -------------------------------------------------------------------------
|
||||
.NOP = {target = .ADDI, src = {.X0, .X0, .LIT, .NONE}, nargs = 0}, // addi x0, x0, 0
|
||||
.MV = {target = .ADDI, src = {.ARG0, .ARG1, .LIT, .NONE}, nargs = 2}, // addi rd, rs, 0
|
||||
.NOT = {target = .XORI, src = {.ARG0, .ARG1, .LIT, .NONE}, lit = -1, nargs = 2}, // xori rd, rs, -1
|
||||
.NEG = {target = .SUB, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // sub rd, x0, rs
|
||||
.NEGW = {target = .SUBW, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // subw rd, x0, rs (RV64)
|
||||
.SEXT_W = {target = .ADDIW, src = {.ARG0, .ARG1, .LIT, .NONE}, nargs = 2}, // addiw rd, rs, 0 (RV64)
|
||||
.ZEXT_B = {target = .ANDI, src = {.ARG0, .ARG1, .LIT, .NONE}, lit = 255, nargs = 2}, // andi rd, rs, 255
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Set-if-condition against zero
|
||||
// -------------------------------------------------------------------------
|
||||
.SEQZ = {target = .SLTIU, src = {.ARG0, .ARG1, .LIT, .NONE}, lit = 1, nargs = 2}, // sltiu rd, rs, 1
|
||||
.SNEZ = {target = .SLTU, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // sltu rd, x0, rs
|
||||
.SLTZ = {target = .SLT, src = {.ARG0, .ARG1, .X0, .NONE}, nargs = 2}, // slt rd, rs, x0
|
||||
.SGTZ = {target = .SLT, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // slt rd, x0, rs
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Branch on comparison with zero (target ops: rs1, rs2, offset)
|
||||
// -------------------------------------------------------------------------
|
||||
.BEQZ = {target = .BEQ, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // beq rs, x0, off
|
||||
.BNEZ = {target = .BNE, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // bne rs, x0, off
|
||||
.BLEZ = {target = .BGE, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // bge x0, rs, off
|
||||
.BGEZ = {target = .BGE, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // bge rs, x0, off
|
||||
.BLTZ = {target = .BLT, src = {.ARG0, .X0, .ARG1, .NONE}, nargs = 2}, // blt rs, x0, off
|
||||
.BGTZ = {target = .BLT, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // blt x0, rs, off
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Branch with the two source registers swapped (encode-only rewrite;
|
||||
// never participates in decode, so the swap is safe)
|
||||
// -------------------------------------------------------------------------
|
||||
.BGT = {target = .BLT, src = {.ARG1, .ARG0, .ARG2, .NONE}, nargs = 3}, // blt rt, rs, off
|
||||
.BLE = {target = .BGE, src = {.ARG1, .ARG0, .ARG2, .NONE}, nargs = 3}, // bge rt, rs, off
|
||||
.BGTU = {target = .BLTU, src = {.ARG1, .ARG0, .ARG2, .NONE}, nargs = 3}, // bltu rt, rs, off
|
||||
.BLEU = {target = .BGEU, src = {.ARG1, .ARG0, .ARG2, .NONE}, nargs = 3}, // bgeu rt, rs, off
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Jumps. JAL_RA / JALR_RA are the single-operand forms that default the
|
||||
// link register to ra; the front-end selects them by argument count vs the
|
||||
// real 2-operand JAL / JALR.
|
||||
// -------------------------------------------------------------------------
|
||||
.J = {target = .JAL, src = {.X0, .ARG0, .NONE, .NONE}, nargs = 1}, // jal x0, off
|
||||
.JAL_RA = {target = .JAL, src = {.X1, .ARG0, .NONE, .NONE}, nargs = 1}, // jal x1, off
|
||||
.JR = {target = .JALR, src = {.X0, .ARG0, .LIT, .NONE}, nargs = 1}, // jalr x0, rs, 0
|
||||
.JALR_RA = {target = .JALR, src = {.X1, .ARG0, .LIT, .NONE}, nargs = 1}, // jalr x1, rs, 0
|
||||
.RET = {target = .JALR, src = {.X0, .X1, .LIT, .NONE}, nargs = 0}, // jalr x0, ra, 0
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Generic CSR access (target ops: rd, csr, rs1/zimm)
|
||||
// -------------------------------------------------------------------------
|
||||
.CSRR = {target = .CSRRS, src = {.ARG0, .ARG1, .X0, .NONE}, nargs = 2}, // csrrs rd, csr, x0
|
||||
.CSRW = {target = .CSRRW, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrw x0, csr, rs
|
||||
.CSRS = {target = .CSRRS, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrs x0, csr, rs
|
||||
.CSRC = {target = .CSRRC, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrc x0, csr, rs
|
||||
.CSRWI = {target = .CSRRWI, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrwi x0, csr, imm
|
||||
.CSRSI = {target = .CSRRSI, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrsi x0, csr, imm
|
||||
.CSRCI = {target = .CSRRCI, src = {.X0, .ARG0, .ARG1, .NONE}, nargs = 2}, // csrrci x0, csr, imm
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Named counter reads — CSR baked in, so nargs = 1 (just rd).
|
||||
// The *h forms read the high word and exist only on RV32.
|
||||
// -------------------------------------------------------------------------
|
||||
.RDCYCLE = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC00, nargs = 1},
|
||||
.RDTIME = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC01, nargs = 1},
|
||||
.RDINSTRET = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC02, nargs = 1},
|
||||
.RDCYCLEH = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC80, nargs = 1, rv32_only = true},
|
||||
.RDTIMEH = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC81, nargs = 1, rv32_only = true},
|
||||
.RDINSTRETH = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0xC82, nargs = 1, rv32_only = true},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// fcsr / frm / fflags accessors. The read forms use CSRRS+x0; the write
|
||||
// forms shown keep the old value in rd (rd, rs). Write-only spellings
|
||||
// (fscsr rs, fsrm rs, fsflags rs, fsrmi imm, fsflagsi imm) default rd = x0
|
||||
// and are dispatched by argument count — add them if you want those too.
|
||||
// -------------------------------------------------------------------------
|
||||
.FRCSR = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0x003, nargs = 1},
|
||||
.FSCSR = {target = .CSRRW, src = {.ARG0, .CSR_LIT, .ARG1, .NONE}, csr = 0x003, nargs = 2},
|
||||
.FRRM = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0x002, nargs = 1},
|
||||
.FSRM = {target = .CSRRW, src = {.ARG0, .CSR_LIT, .ARG1, .NONE}, csr = 0x002, nargs = 2},
|
||||
.FRFLAGS = {target = .CSRRS, src = {.ARG0, .CSR_LIT, .X0, .NONE}, csr = 0x001, nargs = 1},
|
||||
.FSFLAGS = {target = .CSRRW, src = {.ARG0, .CSR_LIT, .ARG1, .NONE}, csr = 0x001, nargs = 2},
|
||||
.FSRMI = {target = .CSRRWI, src = {.ARG0, .CSR_LIT, .ARG1, .NONE}, csr = 0x002, nargs = 2},
|
||||
.FSFLAGSI = {target = .CSRRWI, src = {.ARG0, .CSR_LIT, .ARG1, .NONE}, csr = 0x001, nargs = 2},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// FP moves via sign-injection: fmv=SGNJ(rs,rs), fneg=SGNJN, fabs=SGNJX.
|
||||
// Both source slots are the same user register.
|
||||
// -------------------------------------------------------------------------
|
||||
.FMV_S = {target = .FSGNJ_S, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FABS_S = {target = .FSGNJX_S, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FNEG_S = {target = .FSGNJN_S, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FMV_D = {target = .FSGNJ_D, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FABS_D = {target = .FSGNJX_D, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FNEG_D = {target = .FSGNJN_D, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2},
|
||||
.FMV_H = {target = .FSGNJ_H, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2}, // Zfh
|
||||
.FABS_H = {target = .FSGNJX_H, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2}, // Zfh
|
||||
.FNEG_H = {target = .FSGNJN_H, src = {.ARG0, .ARG1, .ARG1, .NONE}, nargs = 2}, // Zfh
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Bare `fence` == `fence iorw, iorw`; both fence-flag slots take lit = 0xF.
|
||||
// (This assumes the lit fill applies to every .LIT slot. If your filler is
|
||||
// single-slot, make FENCE_ALL a special case instead.)
|
||||
// -------------------------------------------------------------------------
|
||||
.FENCE_ALL = {target = .FENCE, src = {.LIT, .LIT, .NONE, .NONE}, lit = 0xF, nargs = 0},
|
||||
}
|
||||
1080
core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin
Normal file
1080
core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,432 +0,0 @@
|
||||
// rexcode · Brendan Punsky (dotbmp@github), original author
|
||||
|
||||
package rexcode_riscv_tablegen
|
||||
|
||||
// =============================================================================
|
||||
// RISC-V ENCODING_TABLE
|
||||
// =============================================================================
|
||||
//
|
||||
// (bits, mask) model -- same shape as MIPS. `bits` carries the static
|
||||
// opcode/funct3/funct7 pattern; `mask` covers exactly the bits that are
|
||||
// fixed. Operand-driven fields (rd, rs1, rs2, immediates, rounding mode,
|
||||
// aq/rl) land in zero positions of `bits` and are ORed in by the encoder.
|
||||
//
|
||||
// Sections:
|
||||
// §1 RV32I + RV64I base
|
||||
// §2 Zicsr (CSR access) + Zifencei (FENCE.I)
|
||||
// §3 M extension
|
||||
// §4 A extension (atomics)
|
||||
// §5 F extension (single-precision FP)
|
||||
// §6 D extension (double-precision FP)
|
||||
@(rodata)
|
||||
ENCODING_TABLE:= #partial [Mnemonic][]Encoding{
|
||||
.INVALID = {},
|
||||
|
||||
// =========================================================================
|
||||
// §1 RV32I / RV64I base
|
||||
// =========================================================================
|
||||
|
||||
// ---- Upper-immediate ----------------------------------------------------
|
||||
.LUI = { {.LUI, {.GPR,.IMM20,.NONE,.NONE}, {.RD,.IMM_U,.NONE,.NONE}, 0x00000037, MASK_U, .I, {}} },
|
||||
.AUIPC = { {.AUIPC, {.GPR,.IMM20,.NONE,.NONE}, {.RD,.IMM_U,.NONE,.NONE}, 0x00000017, MASK_U, .I, {}} },
|
||||
|
||||
// ---- Jumps --------------------------------------------------------------
|
||||
.JAL = { {.JAL, {.GPR,.REL21,.NONE,.NONE}, {.RD,.IMM_J,.NONE,.NONE}, 0x0000006F, MASK_J, .I, {branch=true}} },
|
||||
.JALR = { {.JALR, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00000067, MASK_OPCODE | MASK_FUNCT3, .I, {branch=true}} },
|
||||
|
||||
// ---- Branches (B-type) --------------------------------------------------
|
||||
.BEQ = { {.BEQ, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00000063, MASK_B, .I, {branch=true}} },
|
||||
.BNE = { {.BNE, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00001063, MASK_B, .I, {branch=true}} },
|
||||
.BLT = { {.BLT, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00004063, MASK_B, .I, {branch=true}} },
|
||||
.BGE = { {.BGE, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00005063, MASK_B, .I, {branch=true}} },
|
||||
.BLTU = { {.BLTU, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00006063, MASK_B, .I, {branch=true}} },
|
||||
.BGEU = { {.BGEU, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00007063, MASK_B, .I, {branch=true}} },
|
||||
|
||||
// ---- Loads (I-type) -----------------------------------------------------
|
||||
.LB = { {.LB, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00000003, MASK_I, .I, {}} },
|
||||
.LH = { {.LH, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00001003, MASK_I, .I, {}} },
|
||||
.LW = { {.LW, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00002003, MASK_I, .I, {}} },
|
||||
.LBU = { {.LBU, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00004003, MASK_I, .I, {}} },
|
||||
.LHU = { {.LHU, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00005003, MASK_I, .I, {}} },
|
||||
.LWU = { {.LWU, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00006003, MASK_I, .I, {rv64_only=true}} },
|
||||
.LD = { {.LD, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00003003, MASK_I, .I, {rv64_only=true}} },
|
||||
|
||||
// ---- Stores (S-type) ----------------------------------------------------
|
||||
.SB = { {.SB, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00000023, MASK_S, .I, {}} },
|
||||
.SH = { {.SH, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00001023, MASK_S, .I, {}} },
|
||||
.SW = { {.SW, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00002023, MASK_S, .I, {}} },
|
||||
.SD = { {.SD, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00003023, MASK_S, .I, {rv64_only=true}} },
|
||||
|
||||
// ---- Integer reg-imm (I-type ALU) ---------------------------------------
|
||||
.ADDI = { {.ADDI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00000013, MASK_I, .I, {}} },
|
||||
.SLTI = { {.SLTI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00002013, MASK_I, .I, {}} },
|
||||
.SLTIU = { {.SLTIU, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00003013, MASK_I, .I, {}} },
|
||||
.XORI = { {.XORI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00004013, MASK_I, .I, {}} },
|
||||
.ORI = { {.ORI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00006013, MASK_I, .I, {}} },
|
||||
.ANDI = { {.ANDI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00007013, MASK_I, .I, {}} },
|
||||
|
||||
// I-type shifts. RV32 uses 5-bit shamt + funct7; RV64 widens to 6-bit
|
||||
// shamt + funct6. We list the RV64-compatible mask (funct6 fixed,
|
||||
// shamt[5] operand-driven); on RV32 the user must keep shamt < 32.
|
||||
.SLLI = { {.SLLI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x00001013, MASK_OPCODE | MASK_FUNCT3 | 0xFC000000, .I, {}} },
|
||||
.SRLI = { {.SRLI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x00005013, MASK_OPCODE | MASK_FUNCT3 | 0xFC000000, .I, {}} },
|
||||
.SRAI = { {.SRAI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x40005013, MASK_OPCODE | MASK_FUNCT3 | 0xFC000000, .I, {}} },
|
||||
|
||||
// RV64 OP-IMM-32 (operates on low 32 bits, sign-extends result)
|
||||
.ADDIW = { {.ADDIW, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x0000001B, MASK_I, .I, {rv64_only=true}} },
|
||||
.SLLIW = { {.SLLIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x0000101B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SRLIW = { {.SRLIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x0000501B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SRAIW = { {.SRAIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x4000501B, MASK_R, .I, {rv64_only=true}} },
|
||||
|
||||
// ---- Integer reg-reg (R-type) -------------------------------------------
|
||||
.ADD = { {.ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00000033, MASK_R, .I, {}} },
|
||||
.SUB = { {.SUB, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40000033, MASK_R, .I, {}} },
|
||||
.SLL = { {.SLL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00001033, MASK_R, .I, {}} },
|
||||
.SLT = { {.SLT, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00002033, MASK_R, .I, {}} },
|
||||
.SLTU = { {.SLTU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00003033, MASK_R, .I, {}} },
|
||||
.XOR = { {.XOR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00004033, MASK_R, .I, {}} },
|
||||
.SRL = { {.SRL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00005033, MASK_R, .I, {}} },
|
||||
.SRA = { {.SRA, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40005033, MASK_R, .I, {}} },
|
||||
.OR = { {.OR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00006033, MASK_R, .I, {}} },
|
||||
.AND = { {.AND, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00007033, MASK_R, .I, {}} },
|
||||
|
||||
// RV64 OP-32
|
||||
.ADDW = { {.ADDW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0000003B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SUBW = { {.SUBW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x4000003B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SLLW = { {.SLLW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0000103B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SRLW = { {.SRLW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0000503B, MASK_R, .I, {rv64_only=true}} },
|
||||
.SRAW = { {.SRAW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x4000503B, MASK_R, .I, {rv64_only=true}} },
|
||||
|
||||
// ---- Memory ordering ----------------------------------------------------
|
||||
// FENCE encodes pred/succ in bits 27-24 / 23-20. The opcode reserves
|
||||
// these as operand-driven; mask covers opcode + funct3.
|
||||
.FENCE = { {.FENCE, {.FENCE_FLAGS,.FENCE_FLAGS,.NONE,.NONE}, {.FENCE_PRED,.FENCE_SUCC,.NONE,.NONE}, 0x0000000F, MASK_I, .I, {}} },
|
||||
.FENCE_I = { {.FENCE_I, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0000100F, 0xFFFFFFFF, .ZIFENCEI, {}} },
|
||||
|
||||
// ---- System -------------------------------------------------------------
|
||||
.ECALL = { {.ECALL, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000073, 0xFFFFFFFF, .I, {branch=true}} },
|
||||
.EBREAK = { {.EBREAK, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00100073, 0xFFFFFFFF, .I, {branch=true}} },
|
||||
|
||||
// =========================================================================
|
||||
// §2 Zicsr (CSR access)
|
||||
// =========================================================================
|
||||
// CSRRW rd, csr, rs1
|
||||
// CSRRWI rd, csr, zimm5 (zimm5 lives in the RS1 field)
|
||||
|
||||
.CSRRW = { {.CSRRW, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00001073, MASK_I, .ZICSR, {}} },
|
||||
.CSRRS = { {.CSRRS, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00002073, MASK_I, .ZICSR, {}} },
|
||||
.CSRRC = { {.CSRRC, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00003073, MASK_I, .ZICSR, {}} },
|
||||
.CSRRWI = { {.CSRRWI, {.GPR,.CSR,.ZIMM5,.NONE}, {.RD,.CSR_FIELD,.ZIMM_FIELD,.NONE}, 0x00005073, MASK_I, .ZICSR, {}} },
|
||||
.CSRRSI = { {.CSRRSI, {.GPR,.CSR,.ZIMM5,.NONE}, {.RD,.CSR_FIELD,.ZIMM_FIELD,.NONE}, 0x00006073, MASK_I, .ZICSR, {}} },
|
||||
.CSRRCI = { {.CSRRCI, {.GPR,.CSR,.ZIMM5,.NONE}, {.RD,.CSR_FIELD,.ZIMM_FIELD,.NONE}, 0x00007073, MASK_I, .ZICSR, {}} },
|
||||
|
||||
// =========================================================================
|
||||
// §3 M extension (RV32M / RV64M)
|
||||
// =========================================================================
|
||||
// All share opcode 0x33 and funct7 = 0x01.
|
||||
|
||||
.MUL = { {.MUL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02000033, MASK_R, .M, {}} },
|
||||
.MULH = { {.MULH, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02001033, MASK_R, .M, {}} },
|
||||
.MULHSU = { {.MULHSU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02002033, MASK_R, .M, {}} },
|
||||
.MULHU = { {.MULHU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02003033, MASK_R, .M, {}} },
|
||||
.DIV = { {.DIV, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02004033, MASK_R, .M, {}} },
|
||||
.DIVU = { {.DIVU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02005033, MASK_R, .M, {}} },
|
||||
.REM = { {.REM, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02006033, MASK_R, .M, {}} },
|
||||
.REMU = { {.REMU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02007033, MASK_R, .M, {}} },
|
||||
|
||||
// RV64 M-32 variants (opcode 0x3B)
|
||||
.MULW = { {.MULW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200003B, MASK_R, .M, {rv64_only=true}} },
|
||||
.DIVW = { {.DIVW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200403B, MASK_R, .M, {rv64_only=true}} },
|
||||
.DIVUW = { {.DIVUW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200503B, MASK_R, .M, {rv64_only=true}} },
|
||||
.REMW = { {.REMW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200603B, MASK_R, .M, {rv64_only=true}} },
|
||||
.REMUW = { {.REMUW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200703B, MASK_R, .M, {rv64_only=true}} },
|
||||
|
||||
// =========================================================================
|
||||
// §4 A extension (atomics)
|
||||
// =========================================================================
|
||||
// opcode 0x2F; funct3 = 2 for .W and 3 for .D; funct5 (bits 31-27)
|
||||
// picks the op; bits 26-25 are aq/rl (operand). Mask = opcode +
|
||||
// funct3 + funct5 = 0xF800707F.
|
||||
//
|
||||
// LR.W/LR.D take only one register addr (rd, rs1); rs2 must be 0
|
||||
// and is part of the static mask.
|
||||
//
|
||||
// The address operand uses OFFSET_BASE_A (rs1 only; disp must be 0).
|
||||
|
||||
.LR_W = { {.LR_W, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_A,.NONE,.NONE}, 0x1000202F, 0xF9F0707F, .A, {}} },
|
||||
.SC_W = { {.SC_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x1800202F, 0xF800707F, .A, {}} },
|
||||
.AMOSWAP_W = { {.AMOSWAP_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x0800202F, 0xF800707F, .A, {}} },
|
||||
.AMOADD_W = { {.AMOADD_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x0000202F, 0xF800707F, .A, {}} },
|
||||
.AMOXOR_W = { {.AMOXOR_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x2000202F, 0xF800707F, .A, {}} },
|
||||
.AMOAND_W = { {.AMOAND_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x6000202F, 0xF800707F, .A, {}} },
|
||||
.AMOOR_W = { {.AMOOR_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x4000202F, 0xF800707F, .A, {}} },
|
||||
.AMOMIN_W = { {.AMOMIN_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x8000202F, 0xF800707F, .A, {}} },
|
||||
.AMOMAX_W = { {.AMOMAX_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xA000202F, 0xF800707F, .A, {}} },
|
||||
.AMOMINU_W = { {.AMOMINU_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xC000202F, 0xF800707F, .A, {}} },
|
||||
.AMOMAXU_W = { {.AMOMAXU_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xE000202F, 0xF800707F, .A, {}} },
|
||||
|
||||
.LR_D = { {.LR_D, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_A,.NONE,.NONE}, 0x1000302F, 0xF9F0707F, .A, {rv64_only=true}} },
|
||||
.SC_D = { {.SC_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x1800302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOSWAP_D = { {.AMOSWAP_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x0800302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOADD_D = { {.AMOADD_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x0000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOXOR_D = { {.AMOXOR_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x2000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOAND_D = { {.AMOAND_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x6000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOOR_D = { {.AMOOR_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x4000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOMIN_D = { {.AMOMIN_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x8000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOMAX_D = { {.AMOMAX_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xA000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOMINU_D = { {.AMOMINU_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xC000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
.AMOMAXU_D = { {.AMOMAXU_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xE000302F, 0xF800707F, .A, {rv64_only=true}} },
|
||||
|
||||
// =========================================================================
|
||||
// §5 F extension (single-precision)
|
||||
// =========================================================================
|
||||
//
|
||||
// OP-FP opcode = 0x53. funct7 selects op family. funct3 is normally the
|
||||
// FP rounding mode (operand-driven, fp_round flag) but is fixed for a
|
||||
// few ops (FMV/FCLASS/FEQ/FLT/FLE/FSGNJ*).
|
||||
//
|
||||
// Masks include opcode + funct7 always. funct3 is included only when
|
||||
// it's a fixed selector rather than a rounding mode. rs2 is included
|
||||
// when it's a fixed selector (FCVT/FMV/FCLASS/FSQRT).
|
||||
//
|
||||
// MASK macros used below:
|
||||
// M_OP_F7 :: opcode + funct7
|
||||
// M_OP_F7_RS2 :: + rs2
|
||||
// M_OP_F7_F3 :: + funct3
|
||||
// M_OP_F7_F3_RS2 :: + both
|
||||
|
||||
.FLW = { {.FLW, {.FPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00002007, MASK_I, .F, {}} },
|
||||
.FSW = { {.FSW, {.FPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00002027, MASK_S, .F, {}} },
|
||||
|
||||
// R4-type FMA: opcode + fmt (bits 26-25); fmt=00 for .S
|
||||
.FMADD_S = { {.FMADD_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x00000043, 0x0600007F, .F, {fp_round=true}} },
|
||||
.FMSUB_S = { {.FMSUB_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x00000047, 0x0600007F, .F, {fp_round=true}} },
|
||||
.FNMSUB_S = { {.FNMSUB_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0000004B, 0x0600007F, .F, {fp_round=true}} },
|
||||
.FNMADD_S = { {.FNMADD_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0000004F, 0x0600007F, .F, {fp_round=true}} },
|
||||
|
||||
// R-type with rm
|
||||
.FADD_S = { {.FADD_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00000053, MASK_OPCODE | MASK_FUNCT7, .F, {fp_round=true}} },
|
||||
.FSUB_S = { {.FSUB_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x08000053, MASK_OPCODE | MASK_FUNCT7, .F, {fp_round=true}} },
|
||||
.FMUL_S = { {.FMUL_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x10000053, MASK_OPCODE | MASK_FUNCT7, .F, {fp_round=true}} },
|
||||
.FDIV_S = { {.FDIV_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x18000053, MASK_OPCODE | MASK_FUNCT7, .F, {fp_round=true}} },
|
||||
.FSQRT_S = { {.FSQRT_S, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x58000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true}} },
|
||||
|
||||
// FSGNJ family: funct7 fixed (0x10), funct3 selects sub-op (no rm)
|
||||
.FSGNJ_S = { {.FSGNJ_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20000053, MASK_R, .F, {}} },
|
||||
.FSGNJN_S = { {.FSGNJN_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20001053, MASK_R, .F, {}} },
|
||||
.FSGNJX_S = { {.FSGNJX_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20002053, MASK_R, .F, {}} },
|
||||
|
||||
// FMIN/FMAX: funct7=0x14, funct3 selects min(0)/max(1)
|
||||
.FMIN_S = { {.FMIN_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x28000053, MASK_R, .F, {}} },
|
||||
.FMAX_S = { {.FMAX_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x28001053, MASK_R, .F, {}} },
|
||||
|
||||
// FP -> int convert: rs2 is the type selector
|
||||
.FCVT_W_S = { {.FCVT_W_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true}} },
|
||||
.FCVT_WU_S = { {.FCVT_WU_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0100053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true}} },
|
||||
.FCVT_L_S = { {.FCVT_L_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0200053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true, rv64_only=true}} },
|
||||
.FCVT_LU_S = { {.FCVT_LU_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0300053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true, rv64_only=true}} },
|
||||
|
||||
// FP <- int convert
|
||||
.FCVT_S_W = { {.FCVT_S_W, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true}} },
|
||||
.FCVT_S_WU = { {.FCVT_S_WU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0100053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true}} },
|
||||
.FCVT_S_L = { {.FCVT_S_L, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0200053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true, rv64_only=true}} },
|
||||
.FCVT_S_LU = { {.FCVT_S_LU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0300053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .F, {fp_round=true, rv64_only=true}} },
|
||||
|
||||
// FMV / FCLASS: funct3 fixed (000 for FMV, 001 for FCLASS), rs2=0
|
||||
.FMV_X_W = { {.FMV_X_W, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE0000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .F, {}} },
|
||||
.FMV_W_X = { {.FMV_W_X, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xF0000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .F, {}} },
|
||||
.FCLASS_S = { {.FCLASS_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE0001053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .F, {}} },
|
||||
|
||||
// FP compare: funct7=0x50, funct3 selects EQ(2)/LT(1)/LE(0)
|
||||
.FEQ_S = { {.FEQ_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0002053, MASK_R, .F, {}} },
|
||||
.FLT_S = { {.FLT_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0001053, MASK_R, .F, {}} },
|
||||
.FLE_S = { {.FLE_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0000053, MASK_R, .F, {}} },
|
||||
|
||||
// =========================================================================
|
||||
// §6 D extension (double-precision)
|
||||
// =========================================================================
|
||||
//
|
||||
// Same pattern as F but funct7 low bit = 1 (fmt=01 = D).
|
||||
|
||||
.FLD = { {.FLD, {.FPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00003007, MASK_I, .D, {}} },
|
||||
.FSD = { {.FSD, {.FPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00003027, MASK_S, .D, {}} },
|
||||
|
||||
.FMADD_D = { {.FMADD_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x02000043, 0x0600007F, .D, {fp_round=true}} },
|
||||
.FMSUB_D = { {.FMSUB_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x02000047, 0x0600007F, .D, {fp_round=true}} },
|
||||
.FNMSUB_D = { {.FNMSUB_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0200004B, 0x0600007F, .D, {fp_round=true}} },
|
||||
.FNMADD_D = { {.FNMADD_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0200004F, 0x0600007F, .D, {fp_round=true}} },
|
||||
|
||||
.FADD_D = { {.FADD_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02000053, MASK_OPCODE | MASK_FUNCT7, .D, {fp_round=true}} },
|
||||
.FSUB_D = { {.FSUB_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A000053, MASK_OPCODE | MASK_FUNCT7, .D, {fp_round=true}} },
|
||||
.FMUL_D = { {.FMUL_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x12000053, MASK_OPCODE | MASK_FUNCT7, .D, {fp_round=true}} },
|
||||
.FDIV_D = { {.FDIV_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x1A000053, MASK_OPCODE | MASK_FUNCT7, .D, {fp_round=true}} },
|
||||
.FSQRT_D = { {.FSQRT_D, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x5A000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
|
||||
.FSGNJ_D = { {.FSGNJ_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22000053, MASK_R, .D, {}} },
|
||||
.FSGNJN_D = { {.FSGNJN_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22001053, MASK_R, .D, {}} },
|
||||
.FSGNJX_D = { {.FSGNJX_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22002053, MASK_R, .D, {}} },
|
||||
|
||||
.FMIN_D = { {.FMIN_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2A000053, MASK_R, .D, {}} },
|
||||
.FMAX_D = { {.FMAX_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2A001053, MASK_R, .D, {}} },
|
||||
|
||||
// FCVT between S and D
|
||||
.FCVT_S_D = { {.FCVT_S_D, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x40100053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
.FCVT_D_S = { {.FCVT_D_S, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x42000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
|
||||
// FP -> int (double-source)
|
||||
.FCVT_W_D = { {.FCVT_W_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
.FCVT_WU_D = { {.FCVT_WU_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2100053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
.FCVT_L_D = { {.FCVT_L_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2200053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true, rv64_only=true}} },
|
||||
.FCVT_LU_D = { {.FCVT_LU_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2300053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true, rv64_only=true}} },
|
||||
|
||||
// FP <- int
|
||||
.FCVT_D_W = { {.FCVT_D_W, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
.FCVT_D_WU = { {.FCVT_D_WU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2100053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true}} },
|
||||
.FCVT_D_L = { {.FCVT_D_L, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2200053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true, rv64_only=true}} },
|
||||
.FCVT_D_LU = { {.FCVT_D_LU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2300053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2, .D, {fp_round=true, rv64_only=true}} },
|
||||
|
||||
// FMV / FCLASS double
|
||||
.FMV_X_D = { {.FMV_X_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE2000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .D, {rv64_only=true}} },
|
||||
.FMV_D_X = { {.FMV_D_X, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xF2000053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .D, {rv64_only=true}} },
|
||||
.FCLASS_D = { {.FCLASS_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE2001053, MASK_OPCODE | MASK_FUNCT7 | MASK_RS2 | MASK_FUNCT3, .D, {}} },
|
||||
|
||||
// FP compare double
|
||||
.FEQ_D = { {.FEQ_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2002053, MASK_R, .D, {}} },
|
||||
.FLT_D = { {.FLT_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2001053, MASK_R, .D, {}} },
|
||||
.FLE_D = { {.FLE_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2000053, MASK_R, .D, {}} },
|
||||
|
||||
// =========================================================================
|
||||
// C extension (16-bit compressed)
|
||||
// =========================================================================
|
||||
//
|
||||
// bits/mask use only the low 16 bits; the encoder writes 2 bytes for any
|
||||
// form whose (bits & 3) != 3. The constant-bit pattern places the C
|
||||
// dispatch fields (funct + op) in the low half-word.
|
||||
|
||||
// ---- Quadrant 0 (op = 00) ----------------------------------------------
|
||||
|
||||
// C.ADDI4SPN rd', sp, imm = 000 imm[5:4] imm[9:6] imm[2] imm[3] rd' 00
|
||||
// funct3=000, op=00 -> static bits 0x0000, mask covers funct3+op only
|
||||
// so the imm fields and rd' are operand-driven.
|
||||
.C_ADDI4SPN = { {.C_ADDI4SPN, {.GPR_C, .GPR_SP, .IMM_C8U, .NONE}, {.C_RD_PRIMED, .NONE, .C_IMM_CIW, .NONE}, 0x0000, 0xE003, .C, {}} },
|
||||
|
||||
// C.FLD rd', imm(rs1') = 001 imm[5:3] rs1' imm[7:6] rd' 00 (D)
|
||||
.C_FLD = { {.C_FLD, {.FPR_C, .MEM_C_D, .NONE, .NONE}, {.C_RD_PRIMED, .C_OFFSET_BASE_D, .NONE, .NONE}, 0x2000, 0xE003, .D, {}} },
|
||||
|
||||
// C.LW rd', imm(rs1') = 010 imm[5:3] rs1' imm[2,6] rd' 00
|
||||
.C_LW = { {.C_LW, {.GPR_C, .MEM_C_W, .NONE, .NONE}, {.C_RD_PRIMED, .C_OFFSET_BASE_W, .NONE, .NONE}, 0x4000, 0xE003, .C, {}} },
|
||||
|
||||
// C.LD rd', imm(rs1') = 011 imm[5:3] rs1' imm[7:6] rd' 00 (RV64-only)
|
||||
.C_LD = { {.C_LD, {.GPR_C, .MEM_C_D, .NONE, .NONE}, {.C_RD_PRIMED, .C_OFFSET_BASE_D, .NONE, .NONE}, 0x6000, 0xE003, .C, {rv64_only=true}} },
|
||||
|
||||
// C.FSD rs2', imm(rs1') = 101 imm[5:3] rs1' imm[7:6] rs2' 00
|
||||
.C_FSD = { {.C_FSD, {.FPR_C, .MEM_C_D, .NONE, .NONE}, {.C_RS2_PRIMED, .C_OFFSET_BASE_D, .NONE, .NONE}, 0xA000, 0xE003, .D, {}} },
|
||||
|
||||
// C.SW rs2', imm(rs1') = 110 imm[5:3] rs1' imm[2,6] rs2' 00
|
||||
.C_SW = { {.C_SW, {.GPR_C, .MEM_C_W, .NONE, .NONE}, {.C_RS2_PRIMED, .C_OFFSET_BASE_W, .NONE, .NONE}, 0xC000, 0xE003, .C, {}} },
|
||||
|
||||
// C.SD rs2', imm(rs1') = 111 imm[5:3] rs1' imm[7:6] rs2' 00 (RV64-only)
|
||||
.C_SD = { {.C_SD, {.GPR_C, .MEM_C_D, .NONE, .NONE}, {.C_RS2_PRIMED, .C_OFFSET_BASE_D, .NONE, .NONE}, 0xE000, 0xE003, .C, {rv64_only=true}} },
|
||||
|
||||
// C.FLW rd', imm(rs1') = 011 imm[5:3] rs1' imm[2,6] rd' 00 (RV32-only)
|
||||
.C_FLW = { {.C_FLW, {.FPR_C, .MEM_C_W, .NONE, .NONE}, {.C_RD_PRIMED, .C_OFFSET_BASE_W, .NONE, .NONE}, 0x6000, 0xE003, .F, {rv32_only=true}} },
|
||||
|
||||
// C.FSW rs2', imm(rs1') = 111 imm[5:3] rs1' imm[2,6] rs2' 00 (RV32-only)
|
||||
.C_FSW = { {.C_FSW, {.FPR_C, .MEM_C_W, .NONE, .NONE}, {.C_RS2_PRIMED, .C_OFFSET_BASE_W, .NONE, .NONE}, 0xE000, 0xE003, .F, {rv32_only=true}} },
|
||||
|
||||
// ---- Quadrant 1 (op = 01) ----------------------------------------------
|
||||
|
||||
// C.NOP = 0x0001 = C.ADDI x0, 0 (fully fixed encoding).
|
||||
.C_NOP = { {.C_NOP, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0001, 0xFFFF, .C, {}} },
|
||||
|
||||
// C.ADDI rd, imm = 000 imm[5] rd!=0 imm[4:0] 01
|
||||
.C_ADDI = { {.C_ADDI, {.GPR_NONZERO, .IMM_C6S, .NONE, .NONE}, {.C_RD_RS1, .C_IMM_CI_S, .NONE, .NONE}, 0x0001, 0xE003, .C, {}} },
|
||||
|
||||
// C.JAL imm = 001 imm[11:1] 01 (RV32-only)
|
||||
.C_JAL = { {.C_JAL, {.REL12, .NONE, .NONE, .NONE}, {.C_BRANCH12, .NONE, .NONE, .NONE}, 0x2001, 0xE003, .C, {rv32_only=true, branch=true}} },
|
||||
|
||||
// C.ADDIW rd, imm = 001 imm[5] rd!=0 imm[4:0] 01 (RV64-only)
|
||||
.C_ADDIW = { {.C_ADDIW, {.GPR_NONZERO, .IMM_C6S, .NONE, .NONE}, {.C_RD_RS1, .C_IMM_CI_S, .NONE, .NONE}, 0x2001, 0xE003, .C, {rv64_only=true}} },
|
||||
|
||||
// C.LI rd, imm = 010 imm[5] rd!=0 imm[4:0] 01
|
||||
.C_LI = { {.C_LI, {.GPR_NONZERO, .IMM_C6S, .NONE, .NONE}, {.C_RD_RS1, .C_IMM_CI_S, .NONE, .NONE}, 0x4001, 0xE003, .C, {}} },
|
||||
|
||||
// C.ADDI16SP sp, imm = 011 imm[9] 00010 imm[4,6,8:7,5] 01
|
||||
// rd is fixed at 2 (sp); ensure the form discriminates by checking rd=2.
|
||||
.C_ADDI16SP = { {.C_ADDI16SP, {.GPR_SP, .IMM_C10S, .NONE, .NONE}, {.NONE, .C_IMM_ADDI16SP, .NONE, .NONE}, 0x6101, 0xEF83, .C, {}} },
|
||||
|
||||
// C.LUI rd, imm = 011 imm[17] rd!=0,2 imm[16:12] 01
|
||||
.C_LUI = { {.C_LUI, {.GPR_NONZERO, .IMM_C18S, .NONE, .NONE}, {.C_RD_RS1, .C_IMM_LUI, .NONE, .NONE}, 0x6001, 0xE003, .C, {}} },
|
||||
|
||||
// C.SRLI rd', shamt = 100 shamt[5] 00 rd' shamt[4:0] 01
|
||||
.C_SRLI = { {.C_SRLI, {.GPR_C, .IMM_C6U, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_IMM_CI_U, .NONE, .NONE}, 0x8001, 0xEC03, .C, {}} },
|
||||
|
||||
// C.SRAI rd', shamt = 100 shamt[5] 01 rd' shamt[4:0] 01
|
||||
.C_SRAI = { {.C_SRAI, {.GPR_C, .IMM_C6U, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_IMM_CI_U, .NONE, .NONE}, 0x8401, 0xEC03, .C, {}} },
|
||||
|
||||
// C.ANDI rd', imm = 100 imm[5] 10 rd' imm[4:0] 01
|
||||
.C_ANDI = { {.C_ANDI, {.GPR_C, .IMM_C6S, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_IMM_CI_S, .NONE, .NONE}, 0x8801, 0xEC03, .C, {}} },
|
||||
|
||||
// CA-format reg-reg (op=01, funct6=100011 / 100111 + funct2 picks op):
|
||||
// C.SUB rd', rs2' = 100011 rd' 00 rs2' 01
|
||||
// C.XOR rd', rs2' = 100011 rd' 01 rs2' 01
|
||||
// C.OR rd', rs2' = 100011 rd' 10 rs2' 01
|
||||
// C.AND rd', rs2' = 100011 rd' 11 rs2' 01
|
||||
// C.SUBW rd', rs2' = 100111 rd' 00 rs2' 01 (RV64)
|
||||
// C.ADDW rd', rs2' = 100111 rd' 01 rs2' 01 (RV64)
|
||||
.C_SUB = { {.C_SUB, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x8C01, 0xFC63, .C, {}} },
|
||||
.C_XOR = { {.C_XOR, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x8C21, 0xFC63, .C, {}} },
|
||||
.C_OR = { {.C_OR, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x8C41, 0xFC63, .C, {}} },
|
||||
.C_AND = { {.C_AND, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x8C61, 0xFC63, .C, {}} },
|
||||
.C_SUBW = { {.C_SUBW, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x9C01, 0xFC63, .C, {rv64_only=true}} },
|
||||
.C_ADDW = { {.C_ADDW, {.GPR_C, .GPR_C, .NONE, .NONE}, {.C_RD_RS1_PRIMED, .C_RS2_PRIMED, .NONE, .NONE}, 0x9C21, 0xFC63, .C, {rv64_only=true}} },
|
||||
|
||||
// C.J offset = 101 offset[11:1] 01
|
||||
.C_J = { {.C_J, {.REL12, .NONE, .NONE, .NONE}, {.C_BRANCH12, .NONE, .NONE, .NONE}, 0xA001, 0xE003, .C, {branch=true}} },
|
||||
|
||||
// C.BEQZ rs1', offset[8:1] = 110 offset[8,4:3] rs1' offset[7:6,2:1,5] 01
|
||||
.C_BEQZ = { {.C_BEQZ, {.GPR_C, .REL9, .NONE, .NONE}, {.C_RS1_PRIMED, .C_BRANCH9, .NONE, .NONE}, 0xC001, 0xE003, .C, {branch=true}} },
|
||||
// C.BNEZ rs1', offset[8:1] = 111 offset[8,4:3] rs1' offset[7:6,2:1,5] 01
|
||||
.C_BNEZ = { {.C_BNEZ, {.GPR_C, .REL9, .NONE, .NONE}, {.C_RS1_PRIMED, .C_BRANCH9, .NONE, .NONE}, 0xE001, 0xE003, .C, {branch=true}} },
|
||||
|
||||
// ---- Quadrant 2 (op = 10) ----------------------------------------------
|
||||
|
||||
// C.SLLI rd, shamt = 000 shamt[5] rd!=0 shamt[4:0] 10
|
||||
.C_SLLI = { {.C_SLLI, {.GPR_NONZERO, .IMM_C6U, .NONE, .NONE}, {.C_RD_RS1, .C_IMM_CI_U, .NONE, .NONE}, 0x0002, 0xE003, .C, {}} },
|
||||
|
||||
// C.FLDSP rd, imm = 001 imm[5] rd imm[4:3,8:6] 10
|
||||
.C_FLDSP = { {.C_FLDSP, {.FPR, .MEM_C_SP_D, .NONE, .NONE}, {.C_RD_RS1, .C_SP_OFFSET_D, .NONE, .NONE}, 0x2002, 0xE003, .D, {}} },
|
||||
|
||||
// C.LWSP rd, imm = 010 imm[5] rd!=0 imm[4:2,7:6] 10
|
||||
.C_LWSP = { {.C_LWSP, {.GPR_NONZERO, .MEM_C_SP_W, .NONE, .NONE}, {.C_RD_RS1, .C_SP_OFFSET_W, .NONE, .NONE}, 0x4002, 0xE003, .C, {}} },
|
||||
|
||||
// C.LDSP rd, imm = 011 imm[5] rd!=0 imm[4:3,8:6] 10 (RV64)
|
||||
.C_LDSP = { {.C_LDSP, {.GPR_NONZERO, .MEM_C_SP_D, .NONE, .NONE}, {.C_RD_RS1, .C_SP_OFFSET_D, .NONE, .NONE}, 0x6002, 0xE003, .C, {rv64_only=true}} },
|
||||
|
||||
// CR-format funct4=1000 / 1001 with rd!=0:
|
||||
// C.JR rs1 = 1000 rs1!=0 00000 10 (rs2=0)
|
||||
// C.MV rd, rs2 = 1000 rd!=0 rs2!=0 10
|
||||
// C.EBREAK = 1001 00000 00000 10 (fully fixed 0x9002)
|
||||
// C.JALR rs1 = 1001 rs1!=0 00000 10 (rs2=0)
|
||||
// C.ADD rd, rs2 = 1001 rd!=0 rs2!=0 10
|
||||
.C_JR = { {.C_JR, {.GPR_NONZERO, .NONE, .NONE, .NONE}, {.C_RD_RS1, .NONE, .NONE, .NONE}, 0x8002, 0xF07F, .C, {branch=true}} },
|
||||
.C_MV = { {.C_MV, {.GPR_NONZERO, .GPR_NONZERO, .NONE, .NONE}, {.C_RD_RS1, .C_RS2, .NONE, .NONE}, 0x8002, 0xF003, .C, {}} },
|
||||
.C_EBREAK = { {.C_EBREAK, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x9002, 0xFFFF, .C, {}} },
|
||||
.C_JALR = { {.C_JALR, {.GPR_NONZERO, .NONE, .NONE, .NONE}, {.C_RD_RS1, .NONE, .NONE, .NONE}, 0x9002, 0xF07F, .C, {branch=true}} },
|
||||
.C_ADD = { {.C_ADD, {.GPR_NONZERO, .GPR_NONZERO, .NONE, .NONE}, {.C_RD_RS1, .C_RS2, .NONE, .NONE}, 0x9002, 0xF003, .C, {}} },
|
||||
|
||||
// C.FSDSP rs2, imm = 101 imm[5:3,8:6] rs2 10
|
||||
.C_FSDSP = { {.C_FSDSP, {.FPR, .MEM_C_SP_D, .NONE, .NONE}, {.C_RS2, .C_IMM_CSS_D, .NONE, .NONE}, 0xA002, 0xE003, .D, {}} },
|
||||
|
||||
// C.SWSP rs2, imm = 110 imm[5:2,7:6] rs2 10
|
||||
.C_SWSP = { {.C_SWSP, {.GPR, .MEM_C_SP_W, .NONE, .NONE}, {.C_RS2, .C_IMM_CSS_W, .NONE, .NONE}, 0xC002, 0xE003, .C, {}} },
|
||||
|
||||
// C.SDSP rs2, imm = 111 imm[5:3,8:6] rs2 10 (RV64)
|
||||
.C_SDSP = { {.C_SDSP, {.GPR, .MEM_C_SP_D, .NONE, .NONE}, {.C_RS2, .C_IMM_CSS_D, .NONE, .NONE}, 0xE002, 0xE003, .C, {rv64_only=true}} },
|
||||
|
||||
// C.FLWSP rd, imm = 011 imm[5] rd imm[4:2,7:6] 10 (RV32-only)
|
||||
.C_FLWSP = { {.C_FLWSP, {.FPR, .MEM_C_SP_W, .NONE, .NONE}, {.C_RD_RS1, .C_SP_OFFSET_W, .NONE, .NONE}, 0x6002, 0xE003, .F, {rv32_only=true}} },
|
||||
|
||||
// C.FSWSP rs2, imm = 111 imm[5:2,7:6] rs2 10 (RV32-only)
|
||||
.C_FSWSP = { {.C_FSWSP, {.FPR, .MEM_C_SP_W, .NONE, .NONE}, {.C_RS2, .C_IMM_CSS_W, .NONE, .NONE}, 0xE002, 0xE003, .F, {rv32_only=true}} },
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import lib "../"
|
||||
// Package-scope aliases so the moved SoT resolves Mnemonic/Encoding unqualified.
|
||||
Encoding :: lib.Encoding
|
||||
Mnemonic :: lib.Mnemonic
|
||||
Clobber :: lib.Clobber
|
||||
|
||||
// The SoT's bit/mask literals reference these field-mask constants.
|
||||
MASK_OPCODE :: lib.MASK_OPCODE
|
||||
@@ -55,12 +56,13 @@ MASK_J :: lib.MASK_J
|
||||
|
||||
Blob :: struct { global, file, typ: string }
|
||||
BLOBS := [?]Blob{
|
||||
{"ENCODE_FORMS", "riscv.encode_forms.bin", "Encoding"},
|
||||
{"ENCODE_RUNS", "riscv.encode_runs.bin", "Encode_Run"},
|
||||
{"DECODE_ENTRIES", "riscv.entries.bin", "Decode_Entry"},
|
||||
{"DECODE_INDEX_OPCODE", "riscv.idx_opcode.bin", "Decode_Index"},
|
||||
{"DECODE_INDEX_OP_FP", "riscv.idx_op_fp.bin", "Decode_Index"},
|
||||
{"DECODE_INDEX_RVC", "riscv.idx_rvc.bin", "Decode_Index"},
|
||||
{"ENCODE_FORMS", "riscv.encode_forms.bin", "Encoding"},
|
||||
{"ENCODE_RUNS", "riscv.encode_runs.bin", "Encode_Run"},
|
||||
{"DECODE_ENTRIES", "riscv.entries.bin", "Decode_Entry"},
|
||||
{"DECODE_INDEX_OPCODE", "riscv.idx_opcode.bin", "Decode_Index"},
|
||||
{"DECODE_INDEX_OP_FP", "riscv.idx_op_fp.bin", "Decode_Index"},
|
||||
{"DECODE_INDEX_RVC", "riscv.idx_rvc.bin", "Decode_Index"},
|
||||
{"CLOBBER_FORMS", "riscv.clobber_forms.bin", "Clobber"},
|
||||
}
|
||||
|
||||
DIR_GEN :: #directory + "/generated/"
|
||||
@@ -98,19 +100,47 @@ emit_encode_tables :: proc() -> (total: int) {
|
||||
sb := strings.builder_make()
|
||||
strings.write_string(&sb, "package rexcode_riscv_generated\n\n")
|
||||
strings.write_string(&sb, "// GENERATED by ../gen.odin -- DO NOT EDIT.\n")
|
||||
strings.write_string(&sb, "// Flattened encode forms + per-mnemonic run index (source: ENCODING_TABLE).\n\n")
|
||||
strings.write_string(&sb, "// Flattened encode forms + per-mnemonic run index (source: INSTRUCTION_TABLE).\n\n")
|
||||
strings.write_string(&sb, "import lib \"../..\"\n\n")
|
||||
|
||||
for m in Mnemonic { total += len(ENCODING_TABLE[m]) }
|
||||
for m in Mnemonic { total += len(INSTRUCTION_TABLE[m]) }
|
||||
|
||||
strings.write_string(&sb, "@(rodata)\n")
|
||||
fmt.sbprintfln(&sb, "ENCODE_FORMS := [%d]lib.Encoding{{", total)
|
||||
for m in Mnemonic {
|
||||
forms := ENCODING_TABLE[m]
|
||||
forms := INSTRUCTION_TABLE[m]
|
||||
if len(forms) == 0 { continue }
|
||||
fmt.sbprintfln(&sb, "\t// .%v", m)
|
||||
for f in forms {
|
||||
write_row(&sb, f.mnemonic, f.ops, f.enc, f.bits, f.mask, f.feature, f.flags)
|
||||
for &form in forms {
|
||||
f := &form.encoding
|
||||
flags := f.flags
|
||||
|
||||
encoding_operand_count: u8 = 0
|
||||
has_implicit := false
|
||||
for op_type in f.ops {
|
||||
if op_type == .NONE { break }
|
||||
if lib.is_implicit_op_inline(op_type) {
|
||||
has_implicit = true
|
||||
} else {
|
||||
encoding_operand_count += 1
|
||||
}
|
||||
}
|
||||
flags.explicit_count = encoding_operand_count
|
||||
flags.has_implicit = has_implicit
|
||||
|
||||
write_row(&sb, f.mnemonic, f.ops, f.enc, f.bits, f.mask, f.feature, flags)
|
||||
}
|
||||
}
|
||||
strings.write_string(&sb, "}\n\n")
|
||||
|
||||
strings.write_string(&sb, "@(rodata)\n")
|
||||
fmt.sbprintfln(&sb, "CLOBBER_FORMS := [%d]lib.Clobber{{", total)
|
||||
for m in Mnemonic {
|
||||
forms := INSTRUCTION_TABLE[m]
|
||||
if len(forms) == 0 { continue }
|
||||
fmt.sbprintfln(&sb, "\t// .%v", m)
|
||||
for &form in forms {
|
||||
write_clobber_row(&sb, form.clobber)
|
||||
}
|
||||
}
|
||||
strings.write_string(&sb, "}\n\n")
|
||||
@@ -121,7 +151,7 @@ emit_encode_tables :: proc() -> (total: int) {
|
||||
strings.write_string(&sb, "ENCODE_RUNS := [lib.Mnemonic]lib.Encode_Run{\n")
|
||||
start := 0
|
||||
for m in Mnemonic {
|
||||
c := len(ENCODING_TABLE[m])
|
||||
c := len(INSTRUCTION_TABLE[m])
|
||||
name := reflect.enum_string(m)
|
||||
fmt.sbprintf(&sb, "\t.%s", name)
|
||||
for _ in 0..<run_w-len(name) { strings.write_byte(&sb, ' ') }
|
||||
@@ -141,7 +171,8 @@ emit_decode_tables :: proc() -> (total: int) {
|
||||
all: [dynamic]Entry
|
||||
defer delete(all)
|
||||
for m in Mnemonic {
|
||||
for f in ENCODING_TABLE[m] {
|
||||
for &form in INSTRUCTION_TABLE[m] {
|
||||
f := &form.encoding
|
||||
e := Entry{
|
||||
mnemonic = f.mnemonic,
|
||||
ops = f.ops,
|
||||
@@ -235,6 +266,64 @@ write_row :: proc(sb: ^strings.Builder, mn: lib.Mnemonic, ops: [4]lib.Operand_Ty
|
||||
mn, ops[0], ops[1], ops[2], ops[3], enc[0], enc[1], enc[2], enc[3], bits, mask, feature, flags_lit(flags))
|
||||
}
|
||||
|
||||
write_clobber_row :: proc(sb: ^strings.Builder, c: lib.Clobber) {
|
||||
write_set :: proc(sb: ^strings.Builder, name: string, set: $T) {
|
||||
strings.write_string(sb, name)
|
||||
strings.write_string(sb, "=")
|
||||
strings.write_string(sb, "{")
|
||||
i := 0
|
||||
for elem in set {
|
||||
if i > 0 { strings.write_string(sb, ", ") }
|
||||
strings.write_string(sb, ".")
|
||||
fmt.sbprintf(sb, "%s", elem)
|
||||
i += 1
|
||||
}
|
||||
strings.write_string(sb, "}")
|
||||
}
|
||||
|
||||
strings.write_string(sb, "\t{")
|
||||
defer strings.write_string(sb, "},\n")
|
||||
i := -1
|
||||
if c.written != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
strings.write_string(sb, "written=")
|
||||
fmt.sbprintf(sb, "%w", c.written)
|
||||
}
|
||||
if c.read != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
strings.write_string(sb, "read=")
|
||||
fmt.sbprintf(sb, "%w", c.read)
|
||||
}
|
||||
if c.implicit_wr != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
write_set(sb, "implicit_wr", c.implicit_wr)
|
||||
}
|
||||
if c.implicit_rd != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
write_set(sb, "implicit_rd", c.implicit_rd)
|
||||
}
|
||||
if c.fflags_wr != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
write_set(sb, "fflags_wr", c.fflags_wr)
|
||||
}
|
||||
if c.reads_frm {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
fmt.sbprintf(sb, "reads_frm=true")
|
||||
}
|
||||
if c.writes_mem {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
fmt.sbprintf(sb, "writes_mem=true")
|
||||
}
|
||||
if c.reads_mem {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
fmt.sbprintf(sb, "reads_mem=true")
|
||||
}
|
||||
if c.side_effects != nil {
|
||||
if i += 1; i > 0 { strings.write_string(sb, ", ") }
|
||||
write_set(sb, "side_effects", c.side_effects)
|
||||
}
|
||||
}
|
||||
|
||||
flags_lit :: proc(f: lib.Encoding_Flags) -> string {
|
||||
parts: [dynamic]string
|
||||
defer delete(parts)
|
||||
@@ -242,6 +331,10 @@ flags_lit :: proc(f: lib.Encoding_Flags) -> string {
|
||||
if f.rv64_only { append(&parts, "rv64_only=true") }
|
||||
if f.branch { append(&parts, "branch=true") }
|
||||
if f.fp_round { append(&parts, "fp_round=true") }
|
||||
if f.explicit_count > 0 {
|
||||
append(&parts, fmt.tprintf("explicit_count=%d", f.explicit_count))
|
||||
}
|
||||
if f.has_implicit { append(&parts, "has_implicit=true") }
|
||||
return strings.join(parts[:], ", ", context.temp_allocator)
|
||||
}
|
||||
|
||||
@@ -268,7 +361,8 @@ emit_writer :: proc() {
|
||||
emit_file(DIR_GEN + "writer.odin", &sb)
|
||||
}
|
||||
|
||||
LOADER_TYPES :: `// -----------------------------------------------------------------------------
|
||||
LOADER_TYPES :: ```
|
||||
// -----------------------------------------------------------------------------
|
||||
// Subsidiary table types (generated scaffolding)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -285,18 +379,19 @@ Decode_Entry :: struct #packed {
|
||||
bits: u32, // 4
|
||||
mask: u32, // 4
|
||||
feature: Feature, // 1
|
||||
flags: Encoding_Flags, // 1
|
||||
flags: Encoding_Flags, // 2
|
||||
}
|
||||
#assert(size_of(Decode_Entry) == 20)
|
||||
#assert(size_of(Decode_Entry) == 21)
|
||||
|
||||
Decode_Index :: struct #packed {
|
||||
start: u16,
|
||||
count: u16,
|
||||
}
|
||||
#assert(size_of(Decode_Index) == 4)
|
||||
`
|
||||
```
|
||||
|
||||
LOADER_ACCESSORS :: `// -----------------------------------------------------------------------------
|
||||
LOADER_ACCESSORS :: ```
|
||||
// -----------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -307,7 +402,15 @@ encoding_forms :: #force_inline proc "contextless" (m: Mnemonic) -> []Encoding {
|
||||
r := ENCODE_RUNS[u16(m)]
|
||||
return ENCODE_FORMS[r.start:][:r.count]
|
||||
}
|
||||
`
|
||||
|
||||
// Per-mnemonic clobber forms: the run of CLOBBER_FORMS belonging to ` + "`m`" + `.
|
||||
// Replaces the old ENCODING_TABLE[m] slice; the returned view is into rodata.
|
||||
@(private, require_results)
|
||||
clobber_forms :: #force_inline proc "contextless" (m: Mnemonic) -> []Clobber {
|
||||
r := ENCODE_RUNS[u16(m)]
|
||||
return CLOBBER_FORMS[r.start:][:r.count]
|
||||
}
|
||||
```
|
||||
|
||||
emit_loader :: proc() {
|
||||
sb := strings.builder_make()
|
||||
|
||||
@@ -8,7 +8,7 @@ package rexcode_riscv_generated
|
||||
import lib "../.."
|
||||
|
||||
@(rodata)
|
||||
DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
DECODE_ENTRIES := [283]lib.Decode_Entry{
|
||||
{ .LB, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00000003, 0x0000707F, .I, {} },
|
||||
{ .LH, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00001003, 0x0000707F, .I, {} },
|
||||
{ .LW, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00002003, 0x0000707F, .I, {} },
|
||||
@@ -18,11 +18,25 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .LD, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00003003, 0x0000707F, .I, {rv64_only=true} },
|
||||
{ .FLW, {.FPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00002007, 0x0000707F, .F, {} },
|
||||
{ .FLD, {.FPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00003007, 0x0000707F, .D, {} },
|
||||
{ .FLH, {.FPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_I,.NONE,.NONE}, 0x00001007, 0x0000707F, .ZFH, {} },
|
||||
{ .FENCE_I, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x0000100F, 0xFFFFFFFF, .ZIFENCEI, {} },
|
||||
{ .FENCE, {.FENCE_FLAGS,.FENCE_FLAGS,.NONE,.NONE}, {.FENCE_PRED,.FENCE_SUCC,.NONE,.NONE}, 0x0000000F, 0x0000707F, .I, {} },
|
||||
{ .CLZ, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x60001013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .CTZ, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x60101013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .CPOP, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x60201013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .SEXT_B, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x60401013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .SEXT_H, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x60501013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .ORC_B, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x28705013, 0xFFF0707F, .ZBB, {} },
|
||||
{ .REV8, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x69805013, 0xFFF0707F, .ZBB, {rv32_only=true} },
|
||||
{ .REV8, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x6B805013, 0xFFF0707F, .ZBB, {rv64_only=true} },
|
||||
{ .SLLI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x00001013, 0xFC00707F, .I, {} },
|
||||
{ .SRLI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x00005013, 0xFC00707F, .I, {} },
|
||||
{ .SRAI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x40005013, 0xFC00707F, .I, {} },
|
||||
{ .RORI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x60005013, 0xFC00707F, .ZBB, {} },
|
||||
{ .BCLRI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x48001013, 0xFC00707F, .ZBS, {} },
|
||||
{ .BEXTI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x48005013, 0xFC00707F, .ZBS, {} },
|
||||
{ .BINVI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x68001013, 0xFC00707F, .ZBS, {} },
|
||||
{ .BSETI, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x28001013, 0xFC00707F, .ZBS, {} },
|
||||
{ .ADDI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00000013, 0x0000707F, .I, {} },
|
||||
{ .SLTI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00002013, 0x0000707F, .I, {} },
|
||||
{ .SLTIU, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00003013, 0x0000707F, .I, {} },
|
||||
@@ -30,9 +44,14 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .ORI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00006013, 0x0000707F, .I, {} },
|
||||
{ .ANDI, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x00007013, 0x0000707F, .I, {} },
|
||||
{ .AUIPC, {.GPR,.IMM20,.NONE,.NONE}, {.RD,.IMM_U,.NONE,.NONE}, 0x00000017, 0x0000007F, .I, {} },
|
||||
{ .CLZW, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x6000101B, 0xFFF0707F, .ZBB, {rv64_only=true} },
|
||||
{ .CTZW, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x6010101B, 0xFFF0707F, .ZBB, {rv64_only=true} },
|
||||
{ .CPOPW, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x6020101B, 0xFFF0707F, .ZBB, {rv64_only=true} },
|
||||
{ .SLLIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x0000101B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
{ .SRLIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x0000501B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
{ .SRAIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x4000501B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
{ .RORIW, {.GPR,.GPR,.IMM5,.NONE}, {.RD,.RS1,.SHAMT5,.NONE}, 0x6000501B, 0xFE00707F, .ZBB, {rv64_only=true} },
|
||||
{ .SLLI_UW, {.GPR,.GPR,.IMM6,.NONE}, {.RD,.RS1,.SHAMT6,.NONE}, 0x0800101B, 0xFC00707F, .ZBA, {rv64_only=true} },
|
||||
{ .ADDIW, {.GPR,.GPR,.IMM12,.NONE}, {.RD,.RS1,.IMM_I,.NONE}, 0x0000001B, 0x0000707F, .I, {rv64_only=true} },
|
||||
{ .SB, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00000023, 0x0000707F, .I, {} },
|
||||
{ .SH, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00001023, 0x0000707F, .I, {} },
|
||||
@@ -40,6 +59,7 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .SD, {.GPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00003023, 0x0000707F, .I, {rv64_only=true} },
|
||||
{ .FSW, {.FPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00002027, 0x0000707F, .F, {} },
|
||||
{ .FSD, {.FPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00003027, 0x0000707F, .D, {} },
|
||||
{ .FSH, {.FPR,.MEM,.NONE,.NONE}, {.RS2,.OFFSET_BASE_S,.NONE,.NONE}, 0x00001027, 0x0000707F, .ZFH, {} },
|
||||
{ .LR_W, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_A,.NONE,.NONE}, 0x1000202F, 0xF9F0707F, .A, {} },
|
||||
{ .LR_D, {.GPR,.MEM,.NONE,.NONE}, {.RD,.OFFSET_BASE_A,.NONE,.NONE}, 0x1000302F, 0xF9F0707F, .A, {rv64_only=true} },
|
||||
{ .SC_W, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0x1800202F, 0xF800707F, .A, {} },
|
||||
@@ -62,6 +82,7 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .AMOMAX_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xA000302F, 0xF800707F, .A, {rv64_only=true} },
|
||||
{ .AMOMINU_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xC000302F, 0xF800707F, .A, {rv64_only=true} },
|
||||
{ .AMOMAXU_D, {.GPR,.GPR,.MEM,.NONE}, {.RD,.RS2,.OFFSET_BASE_A,.NONE}, 0xE000302F, 0xF800707F, .A, {rv64_only=true} },
|
||||
{ .ZEXT_H, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x08004033, 0xFFF0707F, .ZBB, {rv32_only=true} },
|
||||
{ .ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00000033, 0xFE00707F, .I, {} },
|
||||
{ .SUB, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40000033, 0xFE00707F, .I, {} },
|
||||
{ .SLL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00001033, 0xFE00707F, .I, {} },
|
||||
@@ -80,7 +101,29 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .DIVU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02005033, 0xFE00707F, .M, {} },
|
||||
{ .REM, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02006033, 0xFE00707F, .M, {} },
|
||||
{ .REMU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02007033, 0xFE00707F, .M, {} },
|
||||
{ .SH1ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20002033, 0xFE00707F, .ZBA, {} },
|
||||
{ .SH2ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20004033, 0xFE00707F, .ZBA, {} },
|
||||
{ .SH3ADD, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20006033, 0xFE00707F, .ZBA, {} },
|
||||
{ .ANDN, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40007033, 0xFE00707F, .ZBB, {} },
|
||||
{ .ORN, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40006033, 0xFE00707F, .ZBB, {} },
|
||||
{ .XNOR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x40004033, 0xFE00707F, .ZBB, {} },
|
||||
{ .MIN, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A004033, 0xFE00707F, .ZBB, {} },
|
||||
{ .MINU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A005033, 0xFE00707F, .ZBB, {} },
|
||||
{ .MAX, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A006033, 0xFE00707F, .ZBB, {} },
|
||||
{ .MAXU, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A007033, 0xFE00707F, .ZBB, {} },
|
||||
{ .ROL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x60001033, 0xFE00707F, .ZBB, {} },
|
||||
{ .ROR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x60005033, 0xFE00707F, .ZBB, {} },
|
||||
{ .CLMUL, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A001033, 0xFE00707F, .ZBC, {} },
|
||||
{ .CLMULH, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A003033, 0xFE00707F, .ZBC, {} },
|
||||
{ .CLMULR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A002033, 0xFE00707F, .ZBC, {} },
|
||||
{ .BCLR, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x48001033, 0xFE00707F, .ZBS, {} },
|
||||
{ .BEXT, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x48005033, 0xFE00707F, .ZBS, {} },
|
||||
{ .BINV, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x68001033, 0xFE00707F, .ZBS, {} },
|
||||
{ .BSET, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x28001033, 0xFE00707F, .ZBS, {} },
|
||||
{ .CZERO_EQZ, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0E005033, 0xFE00707F, .ZICOND, {} },
|
||||
{ .CZERO_NEZ, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0E007033, 0xFE00707F, .ZICOND, {} },
|
||||
{ .LUI, {.GPR,.IMM20,.NONE,.NONE}, {.RD,.IMM_U,.NONE,.NONE}, 0x00000037, 0x0000007F, .I, {} },
|
||||
{ .ZEXT_H, {.GPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x0800403B, 0xFFF0707F, .ZBB, {rv64_only=true} },
|
||||
{ .ADDW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0000003B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
{ .SUBW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x4000003B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
{ .SLLW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0000103B, 0xFE00707F, .I, {rv64_only=true} },
|
||||
@@ -91,42 +134,69 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .DIVUW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200503B, 0xFE00707F, .M, {rv64_only=true} },
|
||||
{ .REMW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200603B, 0xFE00707F, .M, {rv64_only=true} },
|
||||
{ .REMUW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0200703B, 0xFE00707F, .M, {rv64_only=true} },
|
||||
{ .ADD_UW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0800003B, 0xFE00707F, .ZBA, {rv64_only=true} },
|
||||
{ .SH1ADD_UW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2000203B, 0xFE00707F, .ZBA, {rv64_only=true} },
|
||||
{ .SH2ADD_UW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2000403B, 0xFE00707F, .ZBA, {rv64_only=true} },
|
||||
{ .SH3ADD_UW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2000603B, 0xFE00707F, .ZBA, {rv64_only=true} },
|
||||
{ .ROLW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x6000103B, 0xFE00707F, .ZBB, {rv64_only=true} },
|
||||
{ .RORW, {.GPR,.GPR,.GPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x6000503B, 0xFE00707F, .ZBB, {rv64_only=true} },
|
||||
{ .FMADD_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x00000043, 0x0600007F, .F, {fp_round=true} },
|
||||
{ .FMADD_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x02000043, 0x0600007F, .D, {fp_round=true} },
|
||||
{ .FMADD_H, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x04000043, 0x0600007F, .ZFH, {fp_round=true} },
|
||||
{ .FMSUB_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x00000047, 0x0600007F, .F, {fp_round=true} },
|
||||
{ .FMSUB_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x02000047, 0x0600007F, .D, {fp_round=true} },
|
||||
{ .FMSUB_H, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x04000047, 0x0600007F, .ZFH, {fp_round=true} },
|
||||
{ .FNMSUB_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0000004B, 0x0600007F, .F, {fp_round=true} },
|
||||
{ .FNMSUB_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0200004B, 0x0600007F, .D, {fp_round=true} },
|
||||
{ .FNMSUB_H, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0400004B, 0x0600007F, .ZFH, {fp_round=true} },
|
||||
{ .FNMADD_S, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0000004F, 0x0600007F, .F, {fp_round=true} },
|
||||
{ .FNMADD_D, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0200004F, 0x0600007F, .D, {fp_round=true} },
|
||||
{ .FNMADD_H, {.FPR,.FPR,.FPR,.FPR}, {.RD,.RS1,.RS2,.RS3}, 0x0400004F, 0x0600007F, .ZFH, {fp_round=true} },
|
||||
{ .FADD_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x00000053, 0xFE00007F, .F, {fp_round=true} },
|
||||
{ .FADD_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x02000053, 0xFE00007F, .D, {fp_round=true} },
|
||||
{ .FADD_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x04000053, 0xFE00007F, .ZFH, {fp_round=true} },
|
||||
{ .FSUB_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x08000053, 0xFE00007F, .F, {fp_round=true} },
|
||||
{ .FSUB_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0A000053, 0xFE00007F, .D, {fp_round=true} },
|
||||
{ .FSUB_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x0C000053, 0xFE00007F, .ZFH, {fp_round=true} },
|
||||
{ .FMUL_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x10000053, 0xFE00007F, .F, {fp_round=true} },
|
||||
{ .FMUL_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x12000053, 0xFE00007F, .D, {fp_round=true} },
|
||||
{ .FMUL_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x14000053, 0xFE00007F, .ZFH, {fp_round=true} },
|
||||
{ .FDIV_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x18000053, 0xFE00007F, .F, {fp_round=true} },
|
||||
{ .FDIV_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x1A000053, 0xFE00007F, .D, {fp_round=true} },
|
||||
{ .FDIV_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x1C000053, 0xFE00007F, .ZFH, {fp_round=true} },
|
||||
{ .FSGNJ_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20000053, 0xFE00707F, .F, {} },
|
||||
{ .FSGNJN_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20001053, 0xFE00707F, .F, {} },
|
||||
{ .FSGNJX_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x20002053, 0xFE00707F, .F, {} },
|
||||
{ .FSGNJ_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22000053, 0xFE00707F, .D, {} },
|
||||
{ .FSGNJN_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22001053, 0xFE00707F, .D, {} },
|
||||
{ .FSGNJX_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x22002053, 0xFE00707F, .D, {} },
|
||||
{ .FSGNJ_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x24000053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FSGNJN_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x24001053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FSGNJX_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x24002053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FMIN_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x28000053, 0xFE00707F, .F, {} },
|
||||
{ .FMAX_S, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x28001053, 0xFE00707F, .F, {} },
|
||||
{ .FMIN_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2A000053, 0xFE00707F, .D, {} },
|
||||
{ .FMAX_D, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2A001053, 0xFE00707F, .D, {} },
|
||||
{ .FMIN_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2C000053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FMAX_H, {.FPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0x2C001053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FCVT_S_D, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x40100053, 0xFFF0007F, .D, {fp_round=true} },
|
||||
{ .FCVT_S_H, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x40200053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_D_S, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x42000053, 0xFFF0007F, .D, {fp_round=true} },
|
||||
{ .FCVT_D_H, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x42200053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_H_S, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x44000053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_H_D, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x44100053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FSQRT_S, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x58000053, 0xFFF0007F, .F, {fp_round=true} },
|
||||
{ .FSQRT_D, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x5A000053, 0xFFF0007F, .D, {fp_round=true} },
|
||||
{ .FSQRT_H, {.FPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0x5C000053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FEQ_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0002053, 0xFE00707F, .F, {} },
|
||||
{ .FLT_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0001053, 0xFE00707F, .F, {} },
|
||||
{ .FLE_S, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA0000053, 0xFE00707F, .F, {} },
|
||||
{ .FEQ_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2002053, 0xFE00707F, .D, {} },
|
||||
{ .FLT_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2001053, 0xFE00707F, .D, {} },
|
||||
{ .FLE_D, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA2000053, 0xFE00707F, .D, {} },
|
||||
{ .FEQ_H, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA4002053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FLT_H, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA4001053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FLE_H, {.GPR,.FPR,.FPR,.NONE}, {.RD,.RS1,.RS2,.NONE}, 0xA4000053, 0xFE00707F, .ZFH, {} },
|
||||
{ .FCVT_W_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0000053, 0xFFF0007F, .F, {fp_round=true} },
|
||||
{ .FCVT_WU_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0100053, 0xFFF0007F, .F, {fp_round=true} },
|
||||
{ .FCVT_L_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC0200053, 0xFFF0007F, .F, {rv64_only=true, fp_round=true} },
|
||||
@@ -135,6 +205,10 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .FCVT_WU_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2100053, 0xFFF0007F, .D, {fp_round=true} },
|
||||
{ .FCVT_L_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2200053, 0xFFF0007F, .D, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_LU_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC2300053, 0xFFF0007F, .D, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_W_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC4000053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_WU_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC4100053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_L_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC4200053, 0xFFF0007F, .ZFH, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_LU_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xC4300053, 0xFFF0007F, .ZFH, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_S_W, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0000053, 0xFFF0007F, .F, {fp_round=true} },
|
||||
{ .FCVT_S_WU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0100053, 0xFFF0007F, .F, {fp_round=true} },
|
||||
{ .FCVT_S_L, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD0200053, 0xFFF0007F, .F, {rv64_only=true, fp_round=true} },
|
||||
@@ -143,12 +217,19 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .FCVT_D_WU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2100053, 0xFFF0007F, .D, {fp_round=true} },
|
||||
{ .FCVT_D_L, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2200053, 0xFFF0007F, .D, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_D_LU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD2300053, 0xFFF0007F, .D, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_H_W, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD4000053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_H_WU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD4100053, 0xFFF0007F, .ZFH, {fp_round=true} },
|
||||
{ .FCVT_H_L, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD4200053, 0xFFF0007F, .ZFH, {rv64_only=true, fp_round=true} },
|
||||
{ .FCVT_H_LU, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xD4300053, 0xFFF0007F, .ZFH, {rv64_only=true, fp_round=true} },
|
||||
{ .FMV_X_W, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE0000053, 0xFFF0707F, .F, {} },
|
||||
{ .FCLASS_S, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE0001053, 0xFFF0707F, .F, {} },
|
||||
{ .FCLASS_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE2001053, 0xFFF0707F, .D, {} },
|
||||
{ .FMV_X_D, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE2000053, 0xFFF0707F, .D, {rv64_only=true} },
|
||||
{ .FMV_X_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE4000053, 0xFFF0707F, .ZFH, {} },
|
||||
{ .FCLASS_H, {.GPR,.FPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xE4001053, 0xFFF0707F, .ZFH, {} },
|
||||
{ .FMV_W_X, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xF0000053, 0xFFF0707F, .F, {} },
|
||||
{ .FMV_D_X, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xF2000053, 0xFFF0707F, .D, {rv64_only=true} },
|
||||
{ .FMV_H_X, {.FPR,.GPR,.NONE,.NONE}, {.RD,.RS1,.NONE,.NONE}, 0xF4000053, 0xFFF0707F, .ZFH, {} },
|
||||
{ .BEQ, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00000063, 0x0000707F, .I, {branch=true} },
|
||||
{ .BNE, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00001063, 0x0000707F, .I, {branch=true} },
|
||||
{ .BLT, {.GPR,.GPR,.REL13,.NONE}, {.RS1,.RS2,.IMM_B,.NONE}, 0x00004063, 0x0000707F, .I, {branch=true} },
|
||||
@@ -159,6 +240,10 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
{ .JAL, {.GPR,.REL21,.NONE,.NONE}, {.RD,.IMM_J,.NONE,.NONE}, 0x0000006F, 0x0000007F, .I, {branch=true} },
|
||||
{ .ECALL, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00000073, 0xFFFFFFFF, .I, {branch=true} },
|
||||
{ .EBREAK, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x00100073, 0xFFFFFFFF, .I, {branch=true} },
|
||||
{ .MRET, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x30200073, 0xFFFFFFFF, .PRIV, {branch=true} },
|
||||
{ .SRET, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x10200073, 0xFFFFFFFF, .PRIV, {branch=true} },
|
||||
{ .WFI, {.NONE,.NONE,.NONE,.NONE}, {.NONE,.NONE,.NONE,.NONE}, 0x10500073, 0xFFFFFFFF, .PRIV, {} },
|
||||
{ .SFENCE_VMA, {.GPR,.GPR,.NONE,.NONE}, {.RS1,.RS2,.NONE,.NONE}, 0x12000073, 0xFE007FFF, .PRIV, {} },
|
||||
{ .CSRRW, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00001073, 0x0000707F, .ZICSR, {} },
|
||||
{ .CSRRS, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00002073, 0x0000707F, .ZICSR, {} },
|
||||
{ .CSRRC, {.GPR,.CSR,.GPR,.NONE}, {.RD,.CSR_FIELD,.RS1,.NONE}, 0x00003073, 0x0000707F, .ZICSR, {} },
|
||||
@@ -212,82 +297,95 @@ DECODE_ENTRIES := [198]lib.Decode_Entry{
|
||||
@(rodata)
|
||||
DECODE_INDEX_OPCODE := [128]lib.Decode_Index{
|
||||
0x03 = { 0, 7},
|
||||
0x07 = { 7, 2},
|
||||
0x0F = { 9, 2},
|
||||
0x13 = { 11, 9},
|
||||
0x17 = { 20, 1},
|
||||
0x1B = { 21, 4},
|
||||
0x23 = { 25, 4},
|
||||
0x27 = { 29, 2},
|
||||
0x2F = { 31, 22},
|
||||
0x33 = { 53, 18},
|
||||
0x37 = { 71, 1},
|
||||
0x3B = { 72, 10},
|
||||
0x43 = { 82, 2},
|
||||
0x47 = { 84, 2},
|
||||
0x4B = { 86, 2},
|
||||
0x4F = { 88, 2},
|
||||
0x53 = { 90, 50},
|
||||
0x63 = { 140, 6},
|
||||
0x67 = { 146, 1},
|
||||
0x6F = { 147, 1},
|
||||
0x73 = { 148, 8},
|
||||
0x07 = { 7, 3},
|
||||
0x0F = { 10, 2},
|
||||
0x13 = { 12, 22},
|
||||
0x17 = { 34, 1},
|
||||
0x1B = { 35, 9},
|
||||
0x23 = { 44, 4},
|
||||
0x27 = { 48, 3},
|
||||
0x2F = { 51, 22},
|
||||
0x33 = { 73, 40},
|
||||
0x37 = { 113, 1},
|
||||
0x3B = { 114, 17},
|
||||
0x43 = { 131, 3},
|
||||
0x47 = { 134, 3},
|
||||
0x4B = { 137, 3},
|
||||
0x4F = { 140, 3},
|
||||
0x53 = { 143, 78},
|
||||
0x63 = { 221, 6},
|
||||
0x67 = { 227, 1},
|
||||
0x6F = { 228, 1},
|
||||
0x73 = { 229, 12},
|
||||
}
|
||||
|
||||
@(rodata)
|
||||
DECODE_INDEX_OP_FP := [128]lib.Decode_Index{
|
||||
0x00 = { 90, 1},
|
||||
0x01 = { 91, 1},
|
||||
0x04 = { 92, 1},
|
||||
0x05 = { 93, 1},
|
||||
0x08 = { 94, 1},
|
||||
0x09 = { 95, 1},
|
||||
0x0C = { 96, 1},
|
||||
0x0D = { 97, 1},
|
||||
0x10 = { 98, 3},
|
||||
0x11 = { 101, 3},
|
||||
0x14 = { 104, 2},
|
||||
0x15 = { 106, 2},
|
||||
0x20 = { 108, 1},
|
||||
0x21 = { 109, 1},
|
||||
0x2C = { 110, 1},
|
||||
0x2D = { 111, 1},
|
||||
0x50 = { 112, 3},
|
||||
0x51 = { 115, 3},
|
||||
0x60 = { 118, 4},
|
||||
0x61 = { 122, 4},
|
||||
0x68 = { 126, 4},
|
||||
0x69 = { 130, 4},
|
||||
0x70 = { 134, 2},
|
||||
0x71 = { 136, 2},
|
||||
0x78 = { 138, 1},
|
||||
0x79 = { 139, 1},
|
||||
0x00 = { 143, 1},
|
||||
0x01 = { 144, 1},
|
||||
0x02 = { 145, 1},
|
||||
0x04 = { 146, 1},
|
||||
0x05 = { 147, 1},
|
||||
0x06 = { 148, 1},
|
||||
0x08 = { 149, 1},
|
||||
0x09 = { 150, 1},
|
||||
0x0A = { 151, 1},
|
||||
0x0C = { 152, 1},
|
||||
0x0D = { 153, 1},
|
||||
0x0E = { 154, 1},
|
||||
0x10 = { 155, 3},
|
||||
0x11 = { 158, 3},
|
||||
0x12 = { 161, 3},
|
||||
0x14 = { 164, 2},
|
||||
0x15 = { 166, 2},
|
||||
0x16 = { 168, 2},
|
||||
0x20 = { 170, 2},
|
||||
0x21 = { 172, 2},
|
||||
0x22 = { 174, 2},
|
||||
0x2C = { 176, 1},
|
||||
0x2D = { 177, 1},
|
||||
0x2E = { 178, 1},
|
||||
0x50 = { 179, 3},
|
||||
0x51 = { 182, 3},
|
||||
0x52 = { 185, 3},
|
||||
0x60 = { 188, 4},
|
||||
0x61 = { 192, 4},
|
||||
0x62 = { 196, 4},
|
||||
0x68 = { 200, 4},
|
||||
0x69 = { 204, 4},
|
||||
0x6A = { 208, 4},
|
||||
0x70 = { 212, 2},
|
||||
0x71 = { 214, 2},
|
||||
0x72 = { 216, 2},
|
||||
0x78 = { 218, 1},
|
||||
0x79 = { 219, 1},
|
||||
0x7A = { 220, 1},
|
||||
}
|
||||
|
||||
@(rodata)
|
||||
DECODE_INDEX_RVC := [32]lib.Decode_Index{
|
||||
0x00 = { 156, 1},
|
||||
0x01 = { 157, 2},
|
||||
0x02 = { 159, 1},
|
||||
0x04 = { 160, 1},
|
||||
0x05 = { 161, 2},
|
||||
0x06 = { 163, 1},
|
||||
0x08 = { 164, 1},
|
||||
0x09 = { 165, 1},
|
||||
0x0A = { 166, 1},
|
||||
0x0C = { 167, 2},
|
||||
0x0D = { 169, 2},
|
||||
0x0E = { 171, 2},
|
||||
0x11 = { 173, 9},
|
||||
0x12 = { 182, 5},
|
||||
0x14 = { 187, 1},
|
||||
0x15 = { 188, 1},
|
||||
0x16 = { 189, 1},
|
||||
0x18 = { 190, 1},
|
||||
0x19 = { 191, 1},
|
||||
0x1A = { 192, 1},
|
||||
0x1C = { 193, 2},
|
||||
0x1D = { 195, 1},
|
||||
0x1E = { 196, 2},
|
||||
0x00 = { 241, 1},
|
||||
0x01 = { 242, 2},
|
||||
0x02 = { 244, 1},
|
||||
0x04 = { 245, 1},
|
||||
0x05 = { 246, 2},
|
||||
0x06 = { 248, 1},
|
||||
0x08 = { 249, 1},
|
||||
0x09 = { 250, 1},
|
||||
0x0A = { 251, 1},
|
||||
0x0C = { 252, 2},
|
||||
0x0D = { 254, 2},
|
||||
0x0E = { 256, 2},
|
||||
0x11 = { 258, 9},
|
||||
0x12 = { 267, 5},
|
||||
0x14 = { 272, 1},
|
||||
0x15 = { 273, 1},
|
||||
0x16 = { 274, 1},
|
||||
0x18 = { 275, 1},
|
||||
0x19 = { 276, 1},
|
||||
0x1A = { 277, 1},
|
||||
0x1C = { 278, 2},
|
||||
0x1D = { 280, 1},
|
||||
0x1E = { 281, 2},
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,4 +28,5 @@ main :: proc() {
|
||||
w(TABLES + "riscv.idx_opcode.bin", raw(&DECODE_INDEX_OPCODE, size_of(DECODE_INDEX_OPCODE)))
|
||||
w(TABLES + "riscv.idx_op_fp.bin", raw(&DECODE_INDEX_OP_FP, size_of(DECODE_INDEX_OP_FP)))
|
||||
w(TABLES + "riscv.idx_rvc.bin", raw(&DECODE_INDEX_RVC, size_of(DECODE_INDEX_RVC)))
|
||||
w(TABLES + "riscv.clobber_forms.bin", raw(&CLOBBER_FORMS, size_of(CLOBBER_FORMS)))
|
||||
}
|
||||
|
||||
1012
core/rexcode/isa/riscv/tablegen/instruction_table.odin
Normal file
1012
core/rexcode/isa/riscv/tablegen/instruction_table.odin
Normal file
File diff suppressed because it is too large
Load Diff
@@ -30,35 +30,43 @@ Decode_Entry :: struct #packed {
|
||||
bits: u32, // 4
|
||||
mask: u32, // 4
|
||||
feature: Feature, // 1
|
||||
flags: Encoding_Flags, // 1
|
||||
flags: Encoding_Flags, // 2
|
||||
}
|
||||
#assert(size_of(Decode_Entry) == 20)
|
||||
#assert(size_of(Decode_Entry) == 21)
|
||||
|
||||
Decode_Index :: struct #packed {
|
||||
start: u16,
|
||||
count: u16,
|
||||
}
|
||||
#assert(size_of(Decode_Index) == 4)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Loaded tables (rodata, embedded from tables/*.bin at compile time)
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@(rodata) ENCODE_FORMS := #load("tables/riscv.encode_forms.bin", []Encoding)
|
||||
@(rodata) ENCODE_RUNS := #load("tables/riscv.encode_runs.bin", []Encode_Run)
|
||||
@(rodata) DECODE_ENTRIES := #load("tables/riscv.entries.bin", []Decode_Entry)
|
||||
@(rodata) DECODE_INDEX_OPCODE := #load("tables/riscv.idx_opcode.bin", []Decode_Index)
|
||||
@(rodata) DECODE_INDEX_OP_FP := #load("tables/riscv.idx_op_fp.bin", []Decode_Index)
|
||||
@(rodata) DECODE_INDEX_RVC := #load("tables/riscv.idx_rvc.bin", []Decode_Index)
|
||||
@(rodata) ENCODE_FORMS := #load("tables/riscv.encode_forms.bin", []Encoding)
|
||||
@(rodata) ENCODE_RUNS := #load("tables/riscv.encode_runs.bin", []Encode_Run)
|
||||
@(rodata) DECODE_ENTRIES := #load("tables/riscv.entries.bin", []Decode_Entry)
|
||||
@(rodata) DECODE_INDEX_OPCODE := #load("tables/riscv.idx_opcode.bin", []Decode_Index)
|
||||
@(rodata) DECODE_INDEX_OP_FP := #load("tables/riscv.idx_op_fp.bin", []Decode_Index)
|
||||
@(rodata) DECODE_INDEX_RVC := #load("tables/riscv.idx_rvc.bin", []Decode_Index)
|
||||
@(rodata) CLOBBER_FORMS := #load("tables/riscv.clobber_forms.bin", []Clobber)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Accessors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Per-mnemonic encode forms: the run of ENCODE_FORMS belonging to `m`.
|
||||
// Per-mnemonic encode forms: the run of ENCODE_FORMS belonging to ` + "`m`" + `.
|
||||
// Replaces the old ENCODING_TABLE[m] slice; the returned view is into rodata.
|
||||
@(private, require_results)
|
||||
encoding_forms :: #force_inline proc "contextless" (m: Mnemonic) -> []Encoding {
|
||||
r := ENCODE_RUNS[u16(m)]
|
||||
return ENCODE_FORMS[r.start:][:r.count]
|
||||
}
|
||||
|
||||
// Per-mnemonic clobber forms: the run of CLOBBER_FORMS belonging to ` + "`m`" + `.
|
||||
// Replaces the old ENCODING_TABLE[m] slice; the returned view is into rodata.
|
||||
@(private, require_results)
|
||||
clobber_forms :: #force_inline proc "contextless" (m: Mnemonic) -> []Clobber {
|
||||
r := ENCODE_RUNS[u16(m)]
|
||||
return CLOBBER_FORMS[r.start:][:r.count]
|
||||
}
|
||||
BIN
core/rexcode/isa/riscv/tables/riscv.clobber_forms.bin
Normal file
BIN
core/rexcode/isa/riscv/tables/riscv.clobber_forms.bin
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -309,6 +309,20 @@ main :: proc() {
|
||||
// NOTE: SideEffectFlag_HINT deliberately excluded — inert, may be DCE'd.
|
||||
return ((side_effects & VOLATILE_SE) != 0);
|
||||
}
|
||||
|
||||
u8 is_call_or_mem() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0 ||
|
||||
(cast(u16)implicit_wr & ClobberReg_RSP) != 0;
|
||||
}
|
||||
bool has_control() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0;
|
||||
}
|
||||
bool has_halt() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_HALT) != 0;
|
||||
}
|
||||
bool is_conditional() const {
|
||||
return has_control() && (cast(u16)flags_rd != 0);
|
||||
}
|
||||
};
|
||||
|
||||
void clobber_implicit_regs(StringSet *clobber_registers_set, u16 implicit_regs) {
|
||||
@@ -324,6 +338,41 @@ main :: proc() {
|
||||
}
|
||||
""")
|
||||
strings.write_string(&sb, "\n");
|
||||
strings.write_string(&sb, "\n");
|
||||
strings.write_string(&sb, """
|
||||
enum AliasSrc : u8 {
|
||||
AliasSrc_NONE, // slot unused
|
||||
AliasSrc_ARG0, // user's 1st operand
|
||||
AliasSrc_ARG1, // user's 2nd operand
|
||||
AliasSrc_ARG2, // user's 3rd operand
|
||||
AliasSrc_ZERO, // hardwired zero
|
||||
AliasSrc_LINK, // link register
|
||||
AliasSrc_LIT,
|
||||
};
|
||||
|
||||
struct PseudoAlias {
|
||||
Mnemonic target; // real instruction emitted
|
||||
AliasSrc src[4]; // how to fill target's four operand slots
|
||||
i16 lit; // immediate when a src slot is AliasSrc_LIT
|
||||
u16 csr; // CSR address when a src slot is AliasSrc_CSR_LIT
|
||||
u8 nargs; // operands the user supplies (ARG0..<ARGn)
|
||||
};
|
||||
enum PseudoMnemonic : u16 {
|
||||
PM_INVALID,
|
||||
PSEUDO_MNEMONIC_COUNT
|
||||
};
|
||||
|
||||
PseudoMnemonic pseudo_mnemonic_lookup(String const &name) {
|
||||
return PM_INVALID;
|
||||
}
|
||||
|
||||
PseudoAlias pseudo_alias(u16 pm) {
|
||||
return {};
|
||||
}
|
||||
""")
|
||||
|
||||
strings.write_string(&sb, "\tstatic String const pseudo_mnemonic_strings[PSEUDO_MNEMONIC_COUNT];\n")
|
||||
strings.write_string(&sb, "\n")
|
||||
|
||||
|
||||
strings.write_string(&sb, "\tstatic u16 const register_codes [REG_COUNT];\n")
|
||||
@@ -381,13 +430,6 @@ main :: proc() {
|
||||
fmt.sbprintf(&sb, "return cast(u8)((flags>>%du)&((1u<<%d)-1));", bit_offset, bit_size)
|
||||
strings.write_string(&sb, " }\n")
|
||||
}
|
||||
{
|
||||
bit_offset := intrinsics.type_field_bit_offset(Encoding_Flags, "op_count")
|
||||
bit_size := intrinsics.type_field_bit_size(Encoding_Flags, "op_count")
|
||||
strings.write_string(&sb, "\t\tu8 op_count () const { ")
|
||||
fmt.sbprintf(&sb, "return cast(u8)((flags>>%du)&((1u<<%d)-1));", bit_offset, bit_size)
|
||||
strings.write_string(&sb, " }\n")
|
||||
}
|
||||
{
|
||||
bit_offset := intrinsics.type_field_bit_offset(Encoding_Flags, "lock_ok")
|
||||
strings.write_string(&sb, "\t\tbool lock_ok () const { ")
|
||||
@@ -421,7 +463,8 @@ main :: proc() {
|
||||
|
||||
strings.write_string(&sb, """
|
||||
|
||||
bool init() {
|
||||
bool init(i64 word_size) {
|
||||
gb_unused(word_size);
|
||||
string_map_init(&mnemonic_map, MNEMONIC_COUNT*2);
|
||||
for (u16 m = M_INVALID+1; m < MNEMONIC_COUNT; m++) {
|
||||
string_map_set(&mnemonic_map, mnemonic_strings[m], cast(Mnemonic)m);
|
||||
@@ -437,6 +480,29 @@ main :: proc() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
enum MnemonicSuffix : u8 {
|
||||
MnemonicSuffix_None = 0,
|
||||
};
|
||||
|
||||
bool mnemonic_accepts_suffix(u16 m) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup_ordered(String const &name, u8 *suffixes_) {
|
||||
// NOTE(bill): Do any instructions need a suffix idea?
|
||||
return M_INVALID;
|
||||
}
|
||||
|
||||
enum PseudoMacroMnemonic : u8 {
|
||||
PseudoMacroMnemonic_INVALID,
|
||||
PseudoMacroMnemonic_COUNT
|
||||
};
|
||||
|
||||
PseudoMacroMnemonic pseudo_macro_mnemonic_lookup(String const &name) {
|
||||
return PseudoMacroMnemonic_INVALID;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup(String const &name) {
|
||||
Mnemonic *found = string_map_get(&mnemonic_map, name);
|
||||
return found ? *found : M_INVALID;
|
||||
@@ -483,6 +549,16 @@ main :: proc() {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool integer_reg_width_is_exact() const {
|
||||
return true;
|
||||
}
|
||||
bool float_reg_width_is_exact() const {
|
||||
return true;
|
||||
}
|
||||
bool supports_memory_index_not_just_disp() const {
|
||||
return true;
|
||||
}
|
||||
""")
|
||||
strings.write_string(&sb, "\n\n")
|
||||
|
||||
@@ -748,6 +824,8 @@ main :: proc() {
|
||||
strings.write_string(&sb, "\n");
|
||||
}
|
||||
|
||||
fmt.sbprintf(&sb, "String const Asm_{0:s}::pseudo_mnemonic_strings[Asm_{0:s}::PSEUDO_MNEMONIC_COUNT] {{}};\n", ISA_NAME)
|
||||
|
||||
{
|
||||
fmt.sbprintf(&sb, "u16 const Asm_{0:s}::register_codes[Asm_{0:s}::REG_COUNT] {{\n", ISA_NAME)
|
||||
defer strings.write_string(&sb, "};\n");
|
||||
|
||||
@@ -54,7 +54,9 @@ gb_global String const asm_operand_kind_expected_strings[AsmOperand_COUNT] = {
|
||||
};
|
||||
|
||||
#include "asm_tables_amd64.cpp"
|
||||
#include "asm_tables_riscv.cpp"
|
||||
|
||||
void init_asm_tables() {
|
||||
g_asm_amd64.init();
|
||||
void init_asm_tables(i64 word_size_bytes) {
|
||||
g_asm_amd64.init(word_size_bytes*8);
|
||||
g_asm_riscv.init(word_size_bytes*8);
|
||||
}
|
||||
@@ -312,6 +312,20 @@ struct Asm_amd64 {
|
||||
// NOTE: SideEffectFlag_HINT deliberately excluded — inert, may be DCE'd.
|
||||
return ((side_effects & VOLATILE_SE) != 0);
|
||||
}
|
||||
|
||||
u8 is_call_or_mem() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0 ||
|
||||
(cast(u16)implicit_wr & ClobberReg_RSP) != 0;
|
||||
}
|
||||
bool has_control() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0;
|
||||
}
|
||||
bool has_halt() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_HALT) != 0;
|
||||
}
|
||||
bool is_conditional() const {
|
||||
return has_control() && (cast(u16)flags_rd != 0);
|
||||
}
|
||||
};
|
||||
|
||||
void clobber_implicit_regs(StringSet *clobber_registers_set, u16 implicit_regs) {
|
||||
@@ -325,6 +339,37 @@ struct Asm_amd64 {
|
||||
string_set_update(clobber_registers_set, make_string_c(rname));
|
||||
}
|
||||
}
|
||||
|
||||
enum AliasSrc : u8 {
|
||||
AliasSrc_NONE, // slot unused
|
||||
AliasSrc_ARG0, // user's 1st operand
|
||||
AliasSrc_ARG1, // user's 2nd operand
|
||||
AliasSrc_ARG2, // user's 3rd operand
|
||||
AliasSrc_ZERO, // hardwired zero
|
||||
AliasSrc_LINK, // link register
|
||||
AliasSrc_LIT,
|
||||
};
|
||||
|
||||
struct PseudoAlias {
|
||||
Mnemonic target; // real instruction emitted
|
||||
AliasSrc src[4]; // how to fill target's four operand slots
|
||||
i16 lit; // immediate when a src slot is AliasSrc_LIT
|
||||
u16 csr; // CSR address when a src slot is AliasSrc_CSR_LIT
|
||||
u8 nargs; // operands the user supplies (ARG0..<ARGn)
|
||||
};
|
||||
enum PseudoMnemonic : u16 {
|
||||
PM_INVALID,
|
||||
PSEUDO_MNEMONIC_COUNT
|
||||
};
|
||||
|
||||
PseudoMnemonic pseudo_mnemonic_lookup(String const &name) {
|
||||
return PM_INVALID;
|
||||
}
|
||||
|
||||
PseudoAlias pseudo_alias(u16 pm) {
|
||||
return {};
|
||||
} static String const pseudo_mnemonic_strings[PSEUDO_MNEMONIC_COUNT];
|
||||
|
||||
static u16 const register_codes [REG_COUNT];
|
||||
static String const register_strings[REG_COUNT];
|
||||
|
||||
@@ -424,7 +469,6 @@ struct Asm_amd64 {
|
||||
|
||||
bool has_implicit () const { return ((flags>>21u)&1) != 0; }
|
||||
u8 explicit_count() const { return cast(u8)((flags>>18u)&((1u<<3)-1)); }
|
||||
u8 op_count () const { return cast(u8)((flags>>22u)&((1u<<3)-1)); }
|
||||
bool lock_ok () const { return ((flags>>14u)&1) != 0; }
|
||||
bool rep_ok () const { return ((flags>>15u)&1) != 0; }
|
||||
};
|
||||
@@ -447,7 +491,8 @@ struct Asm_amd64 {
|
||||
StringMap<Prefix> prefix_map;
|
||||
StringMap<Register> register_map;
|
||||
|
||||
bool init() {
|
||||
bool init(i64 word_size) {
|
||||
gb_unused(word_size);
|
||||
string_map_init(&mnemonic_map, MNEMONIC_COUNT*2);
|
||||
for (u16 m = M_INVALID+1; m < MNEMONIC_COUNT; m++) {
|
||||
string_map_set(&mnemonic_map, mnemonic_strings[m], cast(Mnemonic)m);
|
||||
@@ -463,6 +508,29 @@ struct Asm_amd64 {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
enum MnemonicSuffix : u8 {
|
||||
MnemonicSuffix_None = 0,
|
||||
};
|
||||
|
||||
bool mnemonic_accepts_suffix(u16 m) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup_ordered(String const &name, u8 *suffixes_) {
|
||||
// NOTE(bill): Do any instructions need a suffix idea?
|
||||
return M_INVALID;
|
||||
}
|
||||
|
||||
enum PseudoMacroMnemonic : u8 {
|
||||
PseudoMacroMnemonic_INVALID,
|
||||
PseudoMacroMnemonic_COUNT
|
||||
};
|
||||
|
||||
PseudoMacroMnemonic pseudo_macro_mnemonic_lookup(String const &name) {
|
||||
return PseudoMacroMnemonic_INVALID;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup(String const &name) {
|
||||
Mnemonic *found = string_map_get(&mnemonic_map, name);
|
||||
return found ? *found : M_INVALID;
|
||||
@@ -510,6 +578,16 @@ struct Asm_amd64 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool integer_reg_width_is_exact() const {
|
||||
return true;
|
||||
}
|
||||
bool float_reg_width_is_exact() const {
|
||||
return true;
|
||||
}
|
||||
bool supports_memory_index_not_just_disp() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
AsmOperandKind kind_from_operand_type(OperandType type) const {
|
||||
switch (type) {
|
||||
case OP_R8: case OP_R16: case OP_R32: case OP_R64:
|
||||
@@ -773,6 +851,7 @@ String const Asm_amd64::mnemonic_strings[Asm_amd64::MNEMONIC_COUNT] {
|
||||
String const Asm_amd64::prefix_strings[Asm_amd64::PREFIX_COUNT] {
|
||||
str_lit(""), str_lit("es"), str_lit("cs"), str_lit("ss"), str_lit("ds"), str_lit("rex"), str_lit("evex"), str_lit("fs"), str_lit("gs"), str_lit("vex"), str_lit("lock"), str_lit("repne"), str_lit("rep"),
|
||||
};
|
||||
String const Asm_amd64::pseudo_mnemonic_strings[Asm_amd64::PSEUDO_MNEMONIC_COUNT] {};
|
||||
u16 const Asm_amd64::register_codes[Asm_amd64::REG_COUNT] {
|
||||
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
|
||||
271, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526,
|
||||
|
||||
934
src/asm_tables_riscv.cpp
Normal file
934
src/asm_tables_riscv.cpp
Normal file
@@ -0,0 +1,934 @@
|
||||
// =============================================================================
|
||||
// GENERATED FILE - DO NOT EDIT
|
||||
// =============================================================================
|
||||
//
|
||||
// Produces a C++ equivalent of the encoding table from core:rexcode written in Odin
|
||||
// odin run tablegen # Stage A: ENCODING_TABLE -> generated/ + this file
|
||||
// odin run tablegen/generated # Stage B: typed Odin literals -> tables/*.bin
|
||||
// odin run tablegen/cpp-compiler # Stage C: typed Odin literals -> C++ literals
|
||||
//
|
||||
|
||||
|
||||
struct Asm_riscv {
|
||||
enum Mnemonic : u16 {
|
||||
M_INVALID, M_LUI, M_AUIPC, M_JAL, M_JALR, M_BEQ, M_BNE, M_BLT, M_BGE, M_BLTU, M_BGEU, M_LB, M_LH, M_LW, M_LBU, M_LHU,
|
||||
M_SB, M_SH, M_SW, M_LWU, M_LD, M_SD, M_ADDI, M_SLTI, M_SLTIU, M_XORI, M_ORI, M_ANDI, M_SLLI, M_SRLI, M_SRAI, M_ADDIW,
|
||||
M_SLLIW, M_SRLIW, M_SRAIW, M_ADD, M_SUB, M_SLL, M_SLT, M_SLTU, M_XOR, M_SRL, M_SRA, M_OR, M_AND, M_ADDW, M_SUBW, M_SLLW,
|
||||
M_SRLW, M_SRAW, M_FENCE, M_FENCE_I, M_ECALL, M_EBREAK, M_CSRRW, M_CSRRS, M_CSRRC, M_CSRRWI, M_CSRRSI, M_CSRRCI, M_MUL, M_MULH, M_MULHSU, M_MULHU,
|
||||
M_DIV, M_DIVU, M_REM, M_REMU, M_MULW, M_DIVW, M_DIVUW, M_REMW, M_REMUW, M_LR_W, M_SC_W, M_AMOSWAP_W, M_AMOADD_W, M_AMOXOR_W, M_AMOAND_W, M_AMOOR_W,
|
||||
M_AMOMIN_W, M_AMOMAX_W, M_AMOMINU_W, M_AMOMAXU_W, M_LR_D, M_SC_D, M_AMOSWAP_D, M_AMOADD_D, M_AMOXOR_D, M_AMOAND_D, M_AMOOR_D, M_AMOMIN_D, M_AMOMAX_D, M_AMOMINU_D, M_AMOMAXU_D, M_FLW,
|
||||
M_FSW, M_FMADD_S, M_FMSUB_S, M_FNMSUB_S, M_FNMADD_S, M_FADD_S, M_FSUB_S, M_FMUL_S, M_FDIV_S, M_FSQRT_S, M_FSGNJ_S, M_FSGNJN_S, M_FSGNJX_S, M_FMIN_S, M_FMAX_S, M_FCVT_W_S,
|
||||
M_FCVT_WU_S, M_FMV_X_W, M_FEQ_S, M_FLT_S, M_FLE_S, M_FCLASS_S, M_FCVT_S_W, M_FCVT_S_WU, M_FMV_W_X, M_FCVT_L_S, M_FCVT_LU_S, M_FCVT_S_L, M_FCVT_S_LU, M_FLD, M_FSD, M_FMADD_D,
|
||||
M_FMSUB_D, M_FNMSUB_D, M_FNMADD_D, M_FADD_D, M_FSUB_D, M_FMUL_D, M_FDIV_D, M_FSQRT_D, M_FSGNJ_D, M_FSGNJN_D, M_FSGNJX_D, M_FMIN_D, M_FMAX_D, M_FCVT_S_D, M_FCVT_D_S, M_FEQ_D,
|
||||
M_FLT_D, M_FLE_D, M_FCLASS_D, M_FCVT_W_D, M_FCVT_WU_D, M_FCVT_D_W, M_FCVT_D_WU, M_FCVT_L_D, M_FCVT_LU_D, M_FCVT_D_L, M_FCVT_D_LU, M_FMV_X_D, M_FMV_D_X, M_C_NOP, M_C_EBREAK, M_C_ADDI4SPN,
|
||||
M_C_LW, M_C_LD, M_C_SW, M_C_SD, M_C_FLW, M_C_FSW, M_C_FLD, M_C_FSD, M_C_ADDI, M_C_ADDIW, M_C_LI, M_C_LUI, M_C_ADDI16SP, M_C_SRLI, M_C_SRAI, M_C_ANDI,
|
||||
M_C_SUB, M_C_XOR, M_C_OR, M_C_AND, M_C_SUBW, M_C_ADDW, M_C_J, M_C_JAL, M_C_BEQZ, M_C_BNEZ, M_C_SLLI, M_C_LWSP, M_C_LDSP, M_C_SWSP, M_C_SDSP, M_C_FLDSP,
|
||||
M_C_FSDSP, M_C_JR, M_C_JALR, M_C_MV, M_C_ADD, M_C_FLWSP, M_C_FSWSP, M_SH1ADD, M_SH2ADD, M_SH3ADD, M_ADD_UW, M_SH1ADD_UW, M_SH2ADD_UW, M_SH3ADD_UW, M_SLLI_UW, M_ANDN,
|
||||
M_ORN, M_XNOR, M_CLZ, M_CTZ, M_CPOP, M_SEXT_B, M_SEXT_H, M_ZEXT_H, M_MIN, M_MINU, M_MAX, M_MAXU, M_ROL, M_ROR, M_RORI, M_ORC_B,
|
||||
M_REV8, M_CLZW, M_CTZW, M_CPOPW, M_ROLW, M_RORW, M_RORIW, M_CLMUL, M_CLMULH, M_CLMULR, M_BCLR, M_BCLRI, M_BEXT, M_BEXTI, M_BINV, M_BINVI,
|
||||
M_BSET, M_BSETI, M_CZERO_EQZ, M_CZERO_NEZ, M_FLH, M_FSH, M_FMADD_H, M_FMSUB_H, M_FNMSUB_H, M_FNMADD_H, M_FADD_H, M_FSUB_H, M_FMUL_H, M_FDIV_H, M_FSQRT_H, M_FSGNJ_H,
|
||||
M_FSGNJN_H, M_FSGNJX_H, M_FMIN_H, M_FMAX_H, M_FCVT_W_H, M_FCVT_WU_H, M_FCVT_L_H, M_FCVT_LU_H, M_FCVT_H_W, M_FCVT_H_WU, M_FCVT_H_L, M_FCVT_H_LU, M_FCVT_S_H, M_FCVT_H_S, M_FCVT_D_H, M_FCVT_H_D,
|
||||
M_FMV_X_H, M_FMV_H_X, M_FCLASS_H, M_FEQ_H, M_FLT_H, M_FLE_H, M_MRET, M_SRET, M_WFI, M_SFENCE_VMA,
|
||||
|
||||
MNEMONIC_COUNT
|
||||
};
|
||||
static String const mnemonic_strings[MNEMONIC_COUNT];
|
||||
|
||||
enum Prefix : u8 {
|
||||
PREFIX_INVALID,
|
||||
PREFIX_COUNT
|
||||
};
|
||||
enum PrefixKind : u8 { PrefixKind_None };
|
||||
|
||||
|
||||
static const u16 REG_CLASS_NONE = 0x000;
|
||||
static const u16 REG_CLASS_GPR64 = 0x100;
|
||||
static const u16 REG_CLASS_GPR32 = 0x200;
|
||||
static const u16 REG_CLASS_GPR16 = 0x300;
|
||||
static const u16 REG_CLASS_GPR8 = 0x400;
|
||||
static const u16 REG_CLASS_GPR8H = 0x500; // AH, CH, DH, BH - legacy high byte regs
|
||||
static const u16 REG_CLASS_XMM = 0x600;
|
||||
static const u16 REG_CLASS_YMM = 0x700;
|
||||
static const u16 REG_CLASS_ZMM = 0x800;
|
||||
static const u16 REG_CLASS_K = 0x900; // opmask
|
||||
static const u16 REG_CLASS_SEG = 0xA00; // segment
|
||||
static const u16 REG_CLASS_CR = 0xB00; // control
|
||||
static const u16 REG_CLASS_DR = 0xC00; // debug
|
||||
static const u16 REG_CLASS_BND = 0xD00; // bound
|
||||
static const u16 REG_CLASS_MM = 0xE00; // MMX
|
||||
static const u16 REG_CLASS_ST = 0xF00; // x87 FPU
|
||||
|
||||
enum Register : u16 {
|
||||
REG_INVALID, REG_ZERO, REG_RA, REG_SP, REG_GP, REG_TP, REG_T0, REG_T1, REG_T2, REG_S0, REG_S1, REG_A0, REG_A1, REG_A2, REG_A3, REG_A4,
|
||||
REG_A5, REG_A6, REG_A7, REG_S2, REG_S3, REG_S4, REG_S5, REG_S6, REG_S7, REG_S8, REG_S9, REG_S10, REG_S11, REG_T3, REG_T4, REG_T5,
|
||||
REG_T6, REG_FT0, REG_FT1, REG_FT2, REG_FT3, REG_FT4, REG_FT5, REG_FT6, REG_FT7, REG_FS0, REG_FS1, REG_FA0, REG_FA1, REG_FA2, REG_FA3, REG_FA4,
|
||||
REG_FA5, REG_FA6, REG_FA7, REG_FS2, REG_FS3, REG_FS4, REG_FS5, REG_FS6, REG_FS7, REG_FS8, REG_FS9, REG_FS10, REG_FS11, REG_FT8, REG_FT9, REG_FT10,
|
||||
REG_FT11,
|
||||
REG_COUNT
|
||||
};
|
||||
|
||||
|
||||
enum ClobberFFlags : u8 {
|
||||
ClobberFFlag_NV = 1<<0, // invalid operation
|
||||
ClobberFFlag_DZ = 1<<1, // divide by zero
|
||||
ClobberFFlag_OF = 1<<2, // overflow
|
||||
ClobberFFlag_UF = 1<<3, // underflow
|
||||
ClobberFFlag_NX = 1<<4, // inexact
|
||||
};
|
||||
|
||||
enum ClobberRegs : u8 {
|
||||
ClobberReg_RA = 1<<0, // x1, implicit link on C.JAL / C.JALR
|
||||
ClobberReg_SP = 1<<1, // x2, implicit base on the *SP compressed forms
|
||||
};
|
||||
|
||||
static u8 const CLOBBER_REGS_NAMED = ClobberReg_RA|ClobberReg_SP;
|
||||
|
||||
enum SideEffectFlags : u8 {
|
||||
SideEffectFlag_CONTROL = 1<<0, // writes pc: branches, jumps, and trap redirects
|
||||
SideEffectFlag_TRAP = 1<<1, // synchronous environment trap (ECALL / EBREAK)
|
||||
SideEffectFlag_FENCE = 1<<2, // explicit memory-ordering barrier (FENCE)
|
||||
SideEffectFlag_IFENCE = 1<<3, // instruction-fetch synchronization (FENCE.I)
|
||||
SideEffectFlag_ATOMIC = 1<<4, // indivisible memory RMW (AMO*, and the LR/SC pair)
|
||||
SideEffectFlag_RESERVATION = 1<<5, // sets or tests an LR/SC reservation
|
||||
};
|
||||
|
||||
enum OperandSet : u8 {
|
||||
OperandSet_OP0 = 1<<0,
|
||||
OperandSet_OP1 = 1<<1,
|
||||
OperandSet_OP2 = 1<<2,
|
||||
OperandSet_OP3 = 1<<3,
|
||||
};
|
||||
|
||||
u16 clobber_bit_for_reg_name(String const &pin) {
|
||||
static const struct { String name; u16 bit; } table[] = {
|
||||
{str_lit("ra"), ClobberReg_RA},
|
||||
{str_lit("sp"), ClobberReg_SP},
|
||||
{str_lit("x1"), ClobberReg_RA},
|
||||
{str_lit("x2"), ClobberReg_SP},
|
||||
};
|
||||
for (auto const &t : table) {
|
||||
if (pin == t.name) {
|
||||
return t.bit;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const *clobber_reg_bit_name(u16 bit) {
|
||||
switch (bit) {
|
||||
case ClobberReg_RA: return "ra";
|
||||
case ClobberReg_SP: return "sp";
|
||||
}
|
||||
return "<reg>";
|
||||
}
|
||||
|
||||
i32 flag_bit_from_name(String const &name, i32 *width_) {
|
||||
static const struct { String name; i32 bit; } table[] = {
|
||||
// fflags: accrued FP exception flags (fcsr[4:0])
|
||||
{str_lit("nx"), 0}, // Inexact
|
||||
{str_lit("uf"), 1}, // Underflow
|
||||
{str_lit("of"), 2}, // Overflow
|
||||
{str_lit("dz"), 3}, // Divide by Zero
|
||||
{str_lit("nv"), 4}, // Invalid Operation
|
||||
// frm: rounding mode (fcsr[7:5], 3-bit field, low bit)
|
||||
{str_lit("frm"), 5}, // Rounding Mode
|
||||
};
|
||||
|
||||
for (auto const &t : table) {
|
||||
if (name == t.name) {
|
||||
if (width_) {
|
||||
if (t.name == "frm") {
|
||||
*width_ = 3;
|
||||
} else {
|
||||
*width_ = 1;
|
||||
}
|
||||
}
|
||||
return t.bit;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct Clobber {
|
||||
OperandSet written; // operand slots whose register/CSR is written
|
||||
OperandSet read; // operand slots whose register/CSR/mem-base is read
|
||||
ClobberRegs implicit_wr; // implicit reg writes (ra on C.JAL/C.JALR)
|
||||
ClobberRegs implicit_rd; // implicit reg reads (sp on the *SP forms)
|
||||
ClobberFFlags fflags_wr; // accrued exception flags this op may raise
|
||||
bool reads_frm; // consumes the dynamic rounding mode from fcsr
|
||||
bool writes_mem;
|
||||
bool reads_mem;
|
||||
SideEffectFlags side_effects;
|
||||
|
||||
bool implies_clobber_flags() const {
|
||||
return (fflags_wr != 0);
|
||||
}
|
||||
bool implies_clobber_memory() const {
|
||||
return writes_mem || reads_mem ||
|
||||
(side_effects & (SideEffectFlag_FENCE|SideEffectFlag_ATOMIC)) != 0;
|
||||
}
|
||||
bool implies_side_effects() const {
|
||||
return side_effects != 0;
|
||||
}
|
||||
u8 is_call_or_mem() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0 ||
|
||||
(cast(u16)implicit_wr & ClobberReg_SP) != 0;
|
||||
}
|
||||
bool has_control() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_CONTROL) != 0;
|
||||
}
|
||||
bool has_halt() const {
|
||||
return (cast(u16)side_effects & SideEffectFlag_TRAP) != 0;
|
||||
}
|
||||
bool is_conditional() const {
|
||||
return has_control();
|
||||
}
|
||||
};
|
||||
|
||||
void clobber_implicit_regs(StringSet *clobber_registers_set, u16 implicit_regs) {
|
||||
u8 regs = cast(u8)implicit_regs;
|
||||
|
||||
for (u8 bit = 1; bit != 0; bit <<= 1) {
|
||||
if ((regs & bit) == 0) {
|
||||
continue;
|
||||
}
|
||||
char const *rname = clobber_reg_bit_name(bit);
|
||||
string_set_update(clobber_registers_set, make_string_c(rname));
|
||||
}
|
||||
}
|
||||
|
||||
enum AliasSrc : u8 {
|
||||
AliasSrc_NONE, // slot unused
|
||||
AliasSrc_ARG0, // user's 1st operand
|
||||
AliasSrc_ARG1, // user's 2nd operand
|
||||
AliasSrc_ARG2, // user's 3rd operand
|
||||
AliasSrc_ZERO, // hardwired zero (x0)
|
||||
AliasSrc_LINK, // link register (ra / x1)
|
||||
AliasSrc_LIT, // the `lit` field below (immediate literal)
|
||||
AliasSrc_CSR_LIT, // the `csr` field below (fixed 12-bit CSR address)
|
||||
};
|
||||
|
||||
struct PseudoAlias {
|
||||
Mnemonic target; // real instruction emitted
|
||||
AliasSrc src[4]; // how to fill target's four operand slots
|
||||
i16 lit; // immediate when a src slot is AliasSrc_LIT
|
||||
u16 csr; // CSR address when a src slot is AliasSrc_CSR_LIT
|
||||
u8 nargs; // operands the user supplies (ARG0..<ARGn)
|
||||
bool rv32_only; // base gate (the *h counter reads)
|
||||
};
|
||||
|
||||
enum PseudoMnemonic : u16 {
|
||||
PM_INVALID, PM_NOP, PM_MV, PM_NOT,
|
||||
PM_NEG, PM_NEGW, PM_SEXT_W, PM_ZEXT_B,
|
||||
PM_SEQZ, PM_SNEZ, PM_SLTZ, PM_SGTZ,
|
||||
PM_BEQZ, PM_BNEZ, PM_BLEZ, PM_BGEZ,
|
||||
PM_BLTZ, PM_BGTZ, PM_BGT, PM_BLE,
|
||||
PM_BGTU, PM_BLEU, PM_J, PM_JAL_RA,
|
||||
PM_JR, PM_JALR_RA, PM_RET, PM_CSRR,
|
||||
PM_CSRW, PM_CSRS, PM_CSRC, PM_CSRWI,
|
||||
PM_CSRSI, PM_CSRCI, PM_RDCYCLE, PM_RDTIME,
|
||||
PM_RDINSTRET, PM_RDCYCLEH, PM_RDTIMEH, PM_RDINSTRETH,
|
||||
PM_FRCSR, PM_FSCSR, PM_FRRM, PM_FSRM,
|
||||
PM_FRFLAGS, PM_FSFLAGS, PM_FSRMI, PM_FSFLAGSI,
|
||||
PM_FMV_S, PM_FABS_S, PM_FNEG_S, PM_FMV_D,
|
||||
PM_FABS_D, PM_FNEG_D, PM_FMV_H, PM_FABS_H,
|
||||
PM_FNEG_H, PM_FENCE_ALL,
|
||||
PSEUDO_MNEMONIC_COUNT
|
||||
};
|
||||
PseudoMnemonic pseudo_mnemonic_lookup(String const &name) {
|
||||
PseudoMnemonic *found = string_map_get(&pseudo_mnemonic_map, name);
|
||||
return found ? *found : PM_INVALID;
|
||||
}
|
||||
|
||||
PseudoAlias pseudo_alias(u16 pm) {
|
||||
PseudoAlias *pa = (PseudoAlias *)raw_pseudo_aliases;
|
||||
return pa[pm];
|
||||
} static String const pseudo_mnemonic_strings[PSEUDO_MNEMONIC_COUNT];
|
||||
|
||||
static u16 const register_codes [REG_COUNT];
|
||||
static String const register_strings[REG_COUNT];
|
||||
|
||||
|
||||
enum OperandType : u8 {
|
||||
OP_NONE,
|
||||
OP_GPR,
|
||||
OP_FPR,
|
||||
OP_IMM12,
|
||||
OP_IMM12U,
|
||||
OP_IMM5,
|
||||
OP_IMM6,
|
||||
OP_IMM20,
|
||||
OP_REL13,
|
||||
OP_REL21,
|
||||
OP_MEM,
|
||||
OP_CSR,
|
||||
OP_FENCE_FLAGS,
|
||||
OP_ROUND_MODE,
|
||||
OP_ZIMM5,
|
||||
OP_GPR_C,
|
||||
OP_GPR_SP,
|
||||
OP_GPR_NONZERO,
|
||||
OP_FPR_C,
|
||||
OP_IMM_C6S,
|
||||
OP_IMM_C6U,
|
||||
OP_IMM_C8U,
|
||||
OP_IMM_C10S,
|
||||
OP_IMM_C18S,
|
||||
OP_REL9,
|
||||
OP_REL12,
|
||||
OP_MEM_C_W,
|
||||
OP_MEM_C_D,
|
||||
OP_MEM_C_SP_W,
|
||||
OP_MEM_C_SP_D,
|
||||
};
|
||||
|
||||
|
||||
enum OperandEncoding : u8 {
|
||||
ENC_NONE,
|
||||
ENC_RD,
|
||||
ENC_RS1,
|
||||
ENC_RS2,
|
||||
ENC_RS3,
|
||||
ENC_SHAMT5,
|
||||
ENC_SHAMT6,
|
||||
ENC_IMM_I,
|
||||
ENC_IMM_S,
|
||||
ENC_IMM_B,
|
||||
ENC_IMM_U,
|
||||
ENC_IMM_J,
|
||||
ENC_OFFSET_BASE_I,
|
||||
ENC_OFFSET_BASE_S,
|
||||
ENC_OFFSET_BASE_A,
|
||||
ENC_CSR_FIELD,
|
||||
ENC_ZIMM_FIELD,
|
||||
ENC_FENCE_PRED,
|
||||
ENC_FENCE_SUCC,
|
||||
ENC_ROUND_FIELD,
|
||||
ENC_AQRL,
|
||||
ENC_C_RD_RS1,
|
||||
ENC_C_RS2,
|
||||
ENC_C_RD_PRIMED,
|
||||
ENC_C_RS1_PRIMED,
|
||||
ENC_C_RS2_PRIMED,
|
||||
ENC_C_RD_RS1_PRIMED,
|
||||
ENC_C_IMM_CI_S,
|
||||
ENC_C_IMM_CI_U,
|
||||
ENC_C_IMM_CIW,
|
||||
ENC_C_IMM_LUI,
|
||||
ENC_C_IMM_ADDI16SP,
|
||||
ENC_C_IMM_CSS_W,
|
||||
ENC_C_IMM_CSS_D,
|
||||
ENC_C_IMM_CL_W,
|
||||
ENC_C_IMM_CL_D,
|
||||
ENC_C_BRANCH9,
|
||||
ENC_C_BRANCH12,
|
||||
ENC_C_OFFSET_BASE_W,
|
||||
ENC_C_OFFSET_BASE_D,
|
||||
ENC_C_SP_OFFSET_W,
|
||||
ENC_C_SP_OFFSET_D,
|
||||
};
|
||||
|
||||
|
||||
enum Feature : u16 {
|
||||
ENC_I,
|
||||
ENC_M,
|
||||
ENC_A,
|
||||
ENC_F,
|
||||
ENC_D,
|
||||
ENC_ZICSR,
|
||||
ENC_ZIFENCEI,
|
||||
ENC_C,
|
||||
ENC_ZBA,
|
||||
ENC_ZBB,
|
||||
ENC_ZBC,
|
||||
ENC_ZBS,
|
||||
ENC_ZICOND,
|
||||
ENC_ZFH,
|
||||
ENC_PRIV,
|
||||
};
|
||||
|
||||
typedef u8 EncodingFlags; // cannot use a C++ bit field to due lack of portability
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct Encoding {
|
||||
Mnemonic mnemonic;
|
||||
OperandType ops[4];
|
||||
OperandEncoding enc[4];
|
||||
u32 bits;
|
||||
u32 mask;
|
||||
Feature feature;
|
||||
EncodingFlags flags;
|
||||
|
||||
bool has_implicit () const { return ((flags>>7u)&1) != 0; }
|
||||
u8 explicit_count() const { return cast(u8)((flags>>4u)&((1u<<3)-1)); }
|
||||
};
|
||||
#pragma pack(pop)
|
||||
GB_STATIC_ASSERT(gb_size_of(Encoding) == 21);
|
||||
|
||||
|
||||
// Companion run index: ENCODE_RUNS[mnemonic] -> contiguous run in ENCODE_FORMS.
|
||||
struct EncodeRun {
|
||||
u32 start; // start index in ENCODE_FORMS
|
||||
u32 count; // number of forms for this mnemonic
|
||||
};
|
||||
|
||||
|
||||
static EncodeRun const raw_encode_runs [282];
|
||||
static u8 const raw_encode_forms [5943];
|
||||
static u8 const raw_clobber_forms [2547];
|
||||
static u8 const raw_pseudo_aliases[696];
|
||||
|
||||
StringMap<Mnemonic> mnemonic_map;
|
||||
StringMap<Register> register_map;
|
||||
StringMap<PseudoMnemonic> pseudo_mnemonic_map;
|
||||
|
||||
u16 XLEN;
|
||||
u16 FLEN;
|
||||
|
||||
bool init(i64 word_size) {
|
||||
XLEN = cast(u16)word_size;
|
||||
FLEN = cast(u16)word_size;
|
||||
|
||||
string_map_init(&mnemonic_map, MNEMONIC_COUNT*2);
|
||||
for (u16 m = M_INVALID+1; m < MNEMONIC_COUNT; m++) {
|
||||
string_map_set(&mnemonic_map, mnemonic_strings[m], cast(Mnemonic)m);
|
||||
}
|
||||
|
||||
string_map_init(&pseudo_mnemonic_map, PSEUDO_MNEMONIC_COUNT*2);
|
||||
for (u16 m = PM_INVALID+1; m < PSEUDO_MNEMONIC_COUNT; m++) {
|
||||
string_map_set(&pseudo_mnemonic_map, pseudo_mnemonic_strings[m], cast(PseudoMnemonic)m);
|
||||
}
|
||||
|
||||
string_map_init(®ister_map, REG_COUNT*2);
|
||||
for (u16 r = REG_INVALID+1; r < REG_COUNT; r++) {
|
||||
string_map_set(®ister_map, register_strings[r], cast(Register)r);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
enum MnemonicSuffix : u8 {
|
||||
MnemonicSuffix_None = 0,
|
||||
MnemonicSuffix_AQ = 1<<0, // Acquire
|
||||
MnemonicSuffix_RL = 1<<1, // Release
|
||||
};
|
||||
|
||||
bool mnemonic_accepts_suffix(u16 m) const {
|
||||
auto forms = encoding_forms(m);
|
||||
for (auto const &form : forms) {
|
||||
for (auto const &enc : form.enc) {
|
||||
if (enc == ENC_AQRL) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto clobbers = clobber_forms(m);
|
||||
for (auto const &c : clobbers) {
|
||||
if ((cast(u16)c.side_effects & (SideEffectFlag_ATOMIC | SideEffectFlag_RESERVATION)) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup_ordered(String const &name, u8 *suffixes_) {
|
||||
u8 suffixes = 0;
|
||||
String base = {};
|
||||
if (string_ends_with(name, str_lit("_aqrl"))) {
|
||||
suffixes = MnemonicSuffix_AQ | MnemonicSuffix_RL;
|
||||
base = substring(name, 0, name.len - 5);
|
||||
} else if (string_ends_with(name, str_lit("_aq"))) {
|
||||
suffixes = MnemonicSuffix_AQ;
|
||||
base = substring(name, 0, name.len - 3);
|
||||
} else if (string_ends_with(name, str_lit("_rl"))) {
|
||||
suffixes = MnemonicSuffix_RL;
|
||||
base = substring(name, 0, name.len - 3);
|
||||
} else {
|
||||
return M_INVALID;
|
||||
}
|
||||
Mnemonic m = mnemonic_lookup(base);
|
||||
if (m == M_INVALID || !mnemonic_accepts_suffix(cast(u16)m)) {
|
||||
return M_INVALID;
|
||||
}
|
||||
if (suffixes_) *suffixes_ = suffixes;
|
||||
return m;
|
||||
}
|
||||
|
||||
enum PseudoMacroMnemonic : u8 {
|
||||
PseudoMacroMnemonic_INVALID,
|
||||
PseudoMacroMnemonic_LI,
|
||||
PseudoMacroMnemonic_LA,
|
||||
PseudoMacroMnemonic_LLA,
|
||||
PseudoMacroMnemonic_COUNT
|
||||
};
|
||||
|
||||
PseudoMacroMnemonic pseudo_macro_mnemonic_lookup(String const &name) {
|
||||
if (name == "li") { return PseudoMacroMnemonic_LI; }
|
||||
if (name == "la") { return PseudoMacroMnemonic_LA; }
|
||||
if (name == "lla") { return PseudoMacroMnemonic_LLA; }
|
||||
return PseudoMacroMnemonic_INVALID;
|
||||
}
|
||||
|
||||
Mnemonic mnemonic_lookup(String const &name) {
|
||||
Mnemonic *found = string_map_get(&mnemonic_map, name);
|
||||
return found ? *found : M_INVALID;
|
||||
}
|
||||
Prefix prefix_lookup(String const &name) {
|
||||
return PREFIX_INVALID;
|
||||
}
|
||||
static String const prefix_strings[PREFIX_COUNT];
|
||||
|
||||
Register register_lookup(String const &name) {
|
||||
Register *found = string_map_get(®ister_map, name);
|
||||
return found ? *found : REG_INVALID;
|
||||
}
|
||||
Slice<Encoding> encoding_forms(/*Mnemonic*/ u16 m) const {
|
||||
EncodeRun r = raw_encode_runs[m];
|
||||
Encoding *ENCODE_FORMS = cast(Encoding *)raw_encode_forms;
|
||||
return Slice<Encoding>{ENCODE_FORMS+r.start, r.count};
|
||||
}
|
||||
Slice<Clobber> clobber_forms(/*Mnemonic*/ u16 m) const {
|
||||
EncodeRun r = raw_encode_runs[m];
|
||||
Clobber *CLOBBER_FORMS = cast(Clobber *)raw_clobber_forms;
|
||||
return Slice<Clobber>{CLOBBER_FORMS+r.start, r.count};
|
||||
}
|
||||
u16 reg_class(/*Register*/ u16 r) const {
|
||||
return 0xFF00 & r;
|
||||
}
|
||||
// size in bits for register
|
||||
u16 reg_size(Register r) const {
|
||||
switch (reg_class(register_codes[r])) {
|
||||
case REG_CLASS_GPR64: return 64;
|
||||
case REG_CLASS_GPR32: return 32;
|
||||
case REG_CLASS_GPR16: return 16;
|
||||
case REG_CLASS_GPR8: return 8;
|
||||
case REG_CLASS_GPR8H: return 8;
|
||||
case REG_CLASS_XMM: return 128;
|
||||
case REG_CLASS_YMM: return 256;
|
||||
case REG_CLASS_ZMM: return 512;
|
||||
case REG_CLASS_K: return 64;
|
||||
case REG_CLASS_MM: return 64;
|
||||
case REG_CLASS_ST: return 80;
|
||||
case REG_CLASS_SEG: return 16;
|
||||
case REG_CLASS_CR: return 64;
|
||||
case REG_CLASS_DR: return 64;
|
||||
case REG_CLASS_BND: return 128;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool integer_reg_width_is_exact() const {
|
||||
return false;
|
||||
}
|
||||
bool float_reg_width_is_exact() const {
|
||||
return false;
|
||||
}
|
||||
bool supports_memory_index_not_just_disp() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
AsmOperandKind kind_from_operand_type(OperandType type) const {
|
||||
switch (type) {
|
||||
case OP_NONE:
|
||||
return AsmOperand_Invalid;
|
||||
|
||||
// Registers
|
||||
case OP_GPR:
|
||||
case OP_FPR:
|
||||
case OP_GPR_C:
|
||||
case OP_GPR_SP:
|
||||
case OP_GPR_NONZERO:
|
||||
case OP_FPR_C:
|
||||
return AsmOperand_Register;
|
||||
|
||||
case OP_CSR: // 12-bit CSR address; treat as immediate (no CSR reg class exists)
|
||||
// TODO(bill): what should this be?
|
||||
return AsmOperand_Immediate;
|
||||
|
||||
// Immediates (incl. things that ultimately encode as an immediate field:
|
||||
// CSR address, fence flags, rounding mode).
|
||||
case OP_IMM12:
|
||||
case OP_IMM12U:
|
||||
case OP_IMM5:
|
||||
case OP_IMM6:
|
||||
case OP_IMM20:
|
||||
case OP_FENCE_FLAGS: // iorw mask -> 4-bit immediate field
|
||||
case OP_ROUND_MODE: // rm -> 3-bit immediate field
|
||||
case OP_ZIMM5:
|
||||
case OP_IMM_C6S:
|
||||
case OP_IMM_C6U:
|
||||
case OP_IMM_C8U:
|
||||
case OP_IMM_C10S:
|
||||
case OP_IMM_C18S:
|
||||
return AsmOperand_Immediate;
|
||||
|
||||
// Branch/jump targets are written as labels.
|
||||
case OP_REL13:
|
||||
case OP_REL21:
|
||||
case OP_REL9:
|
||||
case OP_REL12:
|
||||
return AsmOperand_Label;
|
||||
|
||||
// Memory
|
||||
case OP_MEM:
|
||||
case OP_MEM_C_W:
|
||||
case OP_MEM_C_D:
|
||||
case OP_MEM_C_SP_W:
|
||||
case OP_MEM_C_SP_D:
|
||||
return AsmOperand_Memory;
|
||||
}
|
||||
return AsmOperand_Invalid;
|
||||
}
|
||||
|
||||
AsmRegClass reg_class_from_operand_type(OperandType type) const {
|
||||
switch (type) {
|
||||
case OP_GPR:
|
||||
case OP_GPR_C:
|
||||
case OP_GPR_SP:
|
||||
case OP_GPR_NONZERO:
|
||||
return AsmRegClass_Integer;
|
||||
|
||||
case OP_FPR:
|
||||
case OP_FPR_C:
|
||||
return AsmRegClass_Float;
|
||||
|
||||
// No vector/mask operand types are present in this list; everything
|
||||
// else (immediates, memory, labels, CSR, etc.) has no register class.
|
||||
default:
|
||||
return AsmRegClass_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
bool operand_type_is_implicit(OperandType t) const {
|
||||
switch (t) {
|
||||
// sp is fixed by the mnemonic (c.addi16sp / c.*sp bases) and isn't a
|
||||
// register the user freely chooses, so it's encoded implicitly.
|
||||
// If your parser actually reads `sp` from the operand text, flip this.
|
||||
case OP_GPR_SP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
AsmRegClass operand_type_reg_class(OperandType t) const {
|
||||
// Same mapping as reg_class_from_operand_type — these two look
|
||||
// redundant; consider collapsing them into one.
|
||||
return reg_class_from_operand_type(t);
|
||||
}
|
||||
|
||||
u16 operand_type_bit_width(OperandType t) const {
|
||||
switch (t) {
|
||||
case OP_NONE:
|
||||
return 0;
|
||||
|
||||
// Registers -> architectural register data width (like OP_R*, OP_XMM).
|
||||
// RISC-V doesn't encode width in the operand type: GPR is XLEN, FPR is
|
||||
// FLEN, both target-config dependent -> treat as data-dependent = 0,
|
||||
// same as x86 OP_K. (Or hardcode 32/64 if your assembler is fixed-config.)
|
||||
// The _C / _SP / _NONZERO variants only restrict *which* regs, not width.
|
||||
case OP_GPR:
|
||||
case OP_GPR_C:
|
||||
case OP_GPR_SP:
|
||||
case OP_GPR_NONZERO:
|
||||
return XLEN;
|
||||
case OP_FPR:
|
||||
case OP_FPR_C:
|
||||
return FLEN;
|
||||
|
||||
// Memory -> access size (like OP_M*). Base OP_MEM's size comes from the opcode.
|
||||
// Compressed forms name the size.
|
||||
case OP_MEM:
|
||||
return 0;
|
||||
case OP_MEM_C_W:
|
||||
case OP_MEM_C_SP_W:
|
||||
return 32;
|
||||
case OP_MEM_C_D:
|
||||
case OP_MEM_C_SP_D:
|
||||
return 64;
|
||||
|
||||
// Immediates -> value width
|
||||
case OP_IMM12:
|
||||
case OP_IMM12U:
|
||||
case OP_CSR:
|
||||
return 12;
|
||||
case OP_IMM5:
|
||||
case OP_ZIMM5:
|
||||
return 5;
|
||||
case OP_IMM6:
|
||||
return 6;
|
||||
case OP_IMM20:
|
||||
return 20;
|
||||
case OP_FENCE_FLAGS:
|
||||
return 4;
|
||||
case OP_ROUND_MODE:
|
||||
return 3;
|
||||
case OP_IMM_C6S:
|
||||
case OP_IMM_C6U:
|
||||
return 6;
|
||||
case OP_IMM_C8U:
|
||||
return 8;
|
||||
case OP_IMM_C10S:
|
||||
return 10;
|
||||
case OP_IMM_C18S:
|
||||
return 18;
|
||||
|
||||
// Rels -> displacement value width
|
||||
case OP_REL13:
|
||||
return 13;
|
||||
case OP_REL21:
|
||||
return 21;
|
||||
case OP_REL9:
|
||||
return 9;
|
||||
case OP_REL12:
|
||||
return 12;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int form_explicit_slot(Encoding const &form, int explicit_index) const {
|
||||
int seen = 0;
|
||||
for (int j = 0; j < gb_count_of(form.ops); j++) {
|
||||
auto t = form.ops[j];
|
||||
if (!t) {
|
||||
break;
|
||||
}
|
||||
if (operand_type_is_implicit(t)) {
|
||||
continue;
|
||||
}
|
||||
if (seen == explicit_index) {
|
||||
return j;
|
||||
}
|
||||
seen += 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool prefix_kind_okay(u8 prefix, Encoding const &form, bool *requires_memory_dest_) const {
|
||||
// RISC-V does not have prefixes
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
gb_global Asm_riscv g_asm_riscv;
|
||||
|
||||
|
||||
|
||||
String const Asm_riscv::prefix_strings[Asm_riscv::PREFIX_COUNT]{};
|
||||
String const Asm_riscv::mnemonic_strings[Asm_riscv::MNEMONIC_COUNT] {
|
||||
str_lit(""), str_lit("lui"), str_lit("auipc"), str_lit("jal"), str_lit("jalr"), str_lit("beq"), str_lit("bne"), str_lit("blt"), str_lit("bge"), str_lit("bltu"), str_lit("bgeu"), str_lit("lb"), str_lit("lh"), str_lit("lw"), str_lit("lbu"), str_lit("lhu"),
|
||||
str_lit("sb"), str_lit("sh"), str_lit("sw"), str_lit("lwu"), str_lit("ld"), str_lit("sd"), str_lit("addi"), str_lit("slti"), str_lit("sltiu"), str_lit("xori"), str_lit("ori"), str_lit("andi"), str_lit("slli"), str_lit("srli"), str_lit("srai"), str_lit("addiw"),
|
||||
str_lit("slliw"), str_lit("srliw"), str_lit("sraiw"), str_lit("add"), str_lit("sub"), str_lit("sll"), str_lit("slt"), str_lit("sltu"), str_lit("xor"), str_lit("srl"), str_lit("sra"), str_lit("or"), str_lit("and"), str_lit("addw"), str_lit("subw"), str_lit("sllw"),
|
||||
str_lit("srlw"), str_lit("sraw"), str_lit("fence"), str_lit("fence_i"), str_lit("ecall"), str_lit("ebreak"), str_lit("csrrw"), str_lit("csrrs"), str_lit("csrrc"), str_lit("csrrwi"), str_lit("csrrsi"), str_lit("csrrci"), str_lit("mul"), str_lit("mulh"), str_lit("mulhsu"), str_lit("mulhu"),
|
||||
str_lit("div"), str_lit("divu"), str_lit("rem"), str_lit("remu"), str_lit("mulw"), str_lit("divw"), str_lit("divuw"), str_lit("remw"), str_lit("remuw"), str_lit("lr_w"), str_lit("sc_w"), str_lit("amoswap_w"), str_lit("amoadd_w"), str_lit("amoxor_w"), str_lit("amoand_w"), str_lit("amoor_w"),
|
||||
str_lit("amomin_w"), str_lit("amomax_w"), str_lit("amominu_w"), str_lit("amomaxu_w"), str_lit("lr_d"), str_lit("sc_d"), str_lit("amoswap_d"), str_lit("amoadd_d"), str_lit("amoxor_d"), str_lit("amoand_d"), str_lit("amoor_d"), str_lit("amomin_d"), str_lit("amomax_d"), str_lit("amominu_d"), str_lit("amomaxu_d"), str_lit("flw"),
|
||||
str_lit("fsw"), str_lit("fmadd_s"), str_lit("fmsub_s"), str_lit("fnmsub_s"), str_lit("fnmadd_s"), str_lit("fadd_s"), str_lit("fsub_s"), str_lit("fmul_s"), str_lit("fdiv_s"), str_lit("fsqrt_s"), str_lit("fsgnj_s"), str_lit("fsgnjn_s"), str_lit("fsgnjx_s"), str_lit("fmin_s"), str_lit("fmax_s"), str_lit("fcvt_w_s"),
|
||||
str_lit("fcvt_wu_s"), str_lit("fmv_x_w"), str_lit("feq_s"), str_lit("flt_s"), str_lit("fle_s"), str_lit("fclass_s"), str_lit("fcvt_s_w"), str_lit("fcvt_s_wu"), str_lit("fmv_w_x"), str_lit("fcvt_l_s"), str_lit("fcvt_lu_s"), str_lit("fcvt_s_l"), str_lit("fcvt_s_lu"), str_lit("fld"), str_lit("fsd"), str_lit("fmadd_d"),
|
||||
str_lit("fmsub_d"), str_lit("fnmsub_d"), str_lit("fnmadd_d"), str_lit("fadd_d"), str_lit("fsub_d"), str_lit("fmul_d"), str_lit("fdiv_d"), str_lit("fsqrt_d"), str_lit("fsgnj_d"), str_lit("fsgnjn_d"), str_lit("fsgnjx_d"), str_lit("fmin_d"), str_lit("fmax_d"), str_lit("fcvt_s_d"), str_lit("fcvt_d_s"), str_lit("feq_d"),
|
||||
str_lit("flt_d"), str_lit("fle_d"), str_lit("fclass_d"), str_lit("fcvt_w_d"), str_lit("fcvt_wu_d"), str_lit("fcvt_d_w"), str_lit("fcvt_d_wu"), str_lit("fcvt_l_d"), str_lit("fcvt_lu_d"), str_lit("fcvt_d_l"), str_lit("fcvt_d_lu"), str_lit("fmv_x_d"), str_lit("fmv_d_x"), str_lit("c_nop"), str_lit("c_ebreak"), str_lit("c_addi4spn"),
|
||||
str_lit("c_lw"), str_lit("c_ld"), str_lit("c_sw"), str_lit("c_sd"), str_lit("c_flw"), str_lit("c_fsw"), str_lit("c_fld"), str_lit("c_fsd"), str_lit("c_addi"), str_lit("c_addiw"), str_lit("c_li"), str_lit("c_lui"), str_lit("c_addi16sp"), str_lit("c_srli"), str_lit("c_srai"), str_lit("c_andi"),
|
||||
str_lit("c_sub"), str_lit("c_xor"), str_lit("c_or"), str_lit("c_and"), str_lit("c_subw"), str_lit("c_addw"), str_lit("c_j"), str_lit("c_jal"), str_lit("c_beqz"), str_lit("c_bnez"), str_lit("c_slli"), str_lit("c_lwsp"), str_lit("c_ldsp"), str_lit("c_swsp"), str_lit("c_sdsp"), str_lit("c_fldsp"),
|
||||
str_lit("c_fsdsp"), str_lit("c_jr"), str_lit("c_jalr"), str_lit("c_mv"), str_lit("c_add"), str_lit("c_flwsp"), str_lit("c_fswsp"), str_lit("sh1add"), str_lit("sh2add"), str_lit("sh3add"), str_lit("add_uw"), str_lit("sh1add_uw"), str_lit("sh2add_uw"), str_lit("sh3add_uw"), str_lit("slli_uw"), str_lit("andn"),
|
||||
str_lit("orn"), str_lit("xnor"), str_lit("clz"), str_lit("ctz"), str_lit("cpop"), str_lit("sext_b"), str_lit("sext_h"), str_lit("zext_h"), str_lit("min"), str_lit("minu"), str_lit("max"), str_lit("maxu"), str_lit("rol"), str_lit("ror"), str_lit("rori"), str_lit("orc_b"),
|
||||
str_lit("rev8"), str_lit("clzw"), str_lit("ctzw"), str_lit("cpopw"), str_lit("rolw"), str_lit("rorw"), str_lit("roriw"), str_lit("clmul"), str_lit("clmulh"), str_lit("clmulr"), str_lit("bclr"), str_lit("bclri"), str_lit("bext"), str_lit("bexti"), str_lit("binv"), str_lit("binvi"),
|
||||
str_lit("bset"), str_lit("bseti"), str_lit("czero_eqz"), str_lit("czero_nez"), str_lit("flh"), str_lit("fsh"), str_lit("fmadd_h"), str_lit("fmsub_h"), str_lit("fnmsub_h"), str_lit("fnmadd_h"), str_lit("fadd_h"), str_lit("fsub_h"), str_lit("fmul_h"), str_lit("fdiv_h"), str_lit("fsqrt_h"), str_lit("fsgnj_h"),
|
||||
str_lit("fsgnjn_h"), str_lit("fsgnjx_h"), str_lit("fmin_h"), str_lit("fmax_h"), str_lit("fcvt_w_h"), str_lit("fcvt_wu_h"), str_lit("fcvt_l_h"), str_lit("fcvt_lu_h"), str_lit("fcvt_h_w"), str_lit("fcvt_h_wu"), str_lit("fcvt_h_l"), str_lit("fcvt_h_lu"), str_lit("fcvt_s_h"), str_lit("fcvt_h_s"), str_lit("fcvt_d_h"), str_lit("fcvt_h_d"),
|
||||
str_lit("fmv_x_h"), str_lit("fmv_h_x"), str_lit("fclass_h"), str_lit("feq_h"), str_lit("flt_h"), str_lit("fle_h"), str_lit("mret"), str_lit("sret"), str_lit("wfi"), str_lit("sfence_vma"),
|
||||
};
|
||||
u16 const Asm_riscv::register_codes[Asm_riscv::REG_COUNT] {
|
||||
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270,
|
||||
271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
|
||||
287, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526,
|
||||
527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
|
||||
543,
|
||||
};
|
||||
String const Asm_riscv::register_strings[Asm_riscv::REG_COUNT] {
|
||||
str_lit(""), str_lit("zero"), str_lit("ra"), str_lit("sp"), str_lit("gp"), str_lit("tp"), str_lit("t0"), str_lit("t1"), str_lit("t2"), str_lit("s0"), str_lit("s1"), str_lit("a0"), str_lit("a1"), str_lit("a2"), str_lit("a3"), str_lit("a4"),
|
||||
str_lit("a5"), str_lit("a6"), str_lit("a7"), str_lit("s2"), str_lit("s3"), str_lit("s4"), str_lit("s5"), str_lit("s6"), str_lit("s7"), str_lit("s8"), str_lit("s9"), str_lit("s10"), str_lit("s11"), str_lit("t3"), str_lit("t4"), str_lit("t5"),
|
||||
str_lit("t6"), str_lit("ft0"), str_lit("ft1"), str_lit("ft2"), str_lit("ft3"), str_lit("ft4"), str_lit("ft5"), str_lit("ft6"), str_lit("ft7"), str_lit("fs0"), str_lit("fs1"), str_lit("fa0"), str_lit("fa1"), str_lit("fa2"), str_lit("fa3"), str_lit("fa4"),
|
||||
str_lit("fa5"), str_lit("fa6"), str_lit("fa7"), str_lit("fs2"), str_lit("fs3"), str_lit("fs4"), str_lit("fs5"), str_lit("fs6"), str_lit("fs7"), str_lit("fs8"), str_lit("fs9"), str_lit("fs10"), str_lit("fs11"), str_lit("ft8"), str_lit("ft9"), str_lit("ft10"),
|
||||
str_lit("ft11"),
|
||||
};
|
||||
String const Asm_riscv::pseudo_mnemonic_strings[Asm_riscv::PSEUDO_MNEMONIC_COUNT] {
|
||||
str_lit(""), str_lit("nop"), str_lit("mv"), str_lit("not"), str_lit("neg"), str_lit("negw"), str_lit("sext_w"), str_lit("zext_b"),
|
||||
str_lit("seqz"), str_lit("snez"), str_lit("sltz"), str_lit("sgtz"), str_lit("beqz"), str_lit("bnez"), str_lit("blez"), str_lit("bgez"),
|
||||
str_lit("bltz"), str_lit("bgtz"), str_lit("bgt"), str_lit("ble"), str_lit("bgtu"), str_lit("bleu"), str_lit("j"), str_lit("jal_ra"),
|
||||
str_lit("jr"), str_lit("jalr_ra"), str_lit("ret"), str_lit("csrr"), str_lit("csrw"), str_lit("csrs"), str_lit("csrc"), str_lit("csrwi"),
|
||||
str_lit("csrsi"), str_lit("csrci"), str_lit("rdcycle"), str_lit("rdtime"), str_lit("rdinstret"), str_lit("rdcycleh"), str_lit("rdtimeh"), str_lit("rdinstreth"),
|
||||
str_lit("frcsr"), str_lit("fscsr"), str_lit("frrm"), str_lit("fsrm"), str_lit("frflags"), str_lit("fsflags"), str_lit("fsrmi"), str_lit("fsflagsi"),
|
||||
str_lit("fmv_s"), str_lit("fabs_s"), str_lit("fneg_s"), str_lit("fmv_d"), str_lit("fabs_d"), str_lit("fneg_d"), str_lit("fmv_h"), str_lit("fabs_h"),
|
||||
str_lit("fneg_h"), str_lit("fence_all"),
|
||||
};
|
||||
Asm_riscv::EncodeRun const Asm_riscv::raw_encode_runs[282] = {
|
||||
{ 0, 0}, { 0, 1}, { 1, 1}, { 2, 1}, { 3, 1}, { 4, 1}, { 5, 1}, { 6, 1}, { 7, 1}, { 8, 1}, { 9, 1}, { 10, 1}, { 11, 1}, { 12, 1}, { 13, 1}, { 14, 1},
|
||||
{ 15, 1}, { 16, 1}, { 17, 1}, { 18, 1}, { 19, 1}, { 20, 1}, { 21, 1}, { 22, 1}, { 23, 1}, { 24, 1}, { 25, 1}, { 26, 1}, { 27, 1}, { 28, 1}, { 29, 1}, { 30, 1},
|
||||
{ 31, 1}, { 32, 1}, { 33, 1}, { 34, 1}, { 35, 1}, { 36, 1}, { 37, 1}, { 38, 1}, { 39, 1}, { 40, 1}, { 41, 1}, { 42, 1}, { 43, 1}, { 44, 1}, { 45, 1}, { 46, 1},
|
||||
{ 47, 1}, { 48, 1}, { 49, 1}, { 50, 1}, { 51, 1}, { 52, 1}, { 53, 1}, { 54, 1}, { 55, 1}, { 56, 1}, { 57, 1}, { 58, 1}, { 59, 1}, { 60, 1}, { 61, 1}, { 62, 1},
|
||||
{ 63, 1}, { 64, 1}, { 65, 1}, { 66, 1}, { 67, 1}, { 68, 1}, { 69, 1}, { 70, 1}, { 71, 1}, { 72, 1}, { 73, 1}, { 74, 1}, { 75, 1}, { 76, 1}, { 77, 1}, { 78, 1},
|
||||
{ 79, 1}, { 80, 1}, { 81, 1}, { 82, 1}, { 83, 1}, { 84, 1}, { 85, 1}, { 86, 1}, { 87, 1}, { 88, 1}, { 89, 1}, { 90, 1}, { 91, 1}, { 92, 1}, { 93, 1}, { 94, 1},
|
||||
{ 95, 1}, { 96, 1}, { 97, 1}, { 98, 1}, { 99, 1}, { 100, 1}, { 101, 1}, { 102, 1}, { 103, 1}, { 104, 1}, { 105, 1}, { 106, 1}, { 107, 1}, { 108, 1}, { 109, 1}, { 110, 1},
|
||||
{ 111, 1}, { 112, 1}, { 113, 1}, { 114, 1}, { 115, 1}, { 116, 1}, { 117, 1}, { 118, 1}, { 119, 1}, { 120, 1}, { 121, 1}, { 122, 1}, { 123, 1}, { 124, 1}, { 125, 1}, { 126, 1},
|
||||
{ 127, 1}, { 128, 1}, { 129, 1}, { 130, 1}, { 131, 1}, { 132, 1}, { 133, 1}, { 134, 1}, { 135, 1}, { 136, 1}, { 137, 1}, { 138, 1}, { 139, 1}, { 140, 1}, { 141, 1}, { 142, 1},
|
||||
{ 143, 1}, { 144, 1}, { 145, 1}, { 146, 1}, { 147, 1}, { 148, 1}, { 149, 1}, { 150, 1}, { 151, 1}, { 152, 1}, { 153, 1}, { 154, 1}, { 155, 1}, { 156, 1}, { 157, 1}, { 158, 1},
|
||||
{ 159, 1}, { 160, 1}, { 161, 1}, { 162, 1}, { 163, 1}, { 164, 1}, { 165, 1}, { 166, 1}, { 167, 1}, { 168, 1}, { 169, 1}, { 170, 1}, { 171, 1}, { 172, 1}, { 173, 1}, { 174, 1},
|
||||
{ 175, 1}, { 176, 1}, { 177, 1}, { 178, 1}, { 179, 1}, { 180, 1}, { 181, 1}, { 182, 1}, { 183, 1}, { 184, 1}, { 185, 1}, { 186, 1}, { 187, 1}, { 188, 1}, { 189, 1}, { 190, 1},
|
||||
{ 191, 1}, { 192, 1}, { 193, 1}, { 194, 1}, { 195, 1}, { 196, 1}, { 197, 1}, { 198, 1}, { 199, 1}, { 200, 1}, { 201, 1}, { 202, 1}, { 203, 1}, { 204, 1}, { 205, 1}, { 206, 1},
|
||||
{ 207, 1}, { 208, 1}, { 209, 1}, { 210, 1}, { 211, 1}, { 212, 1}, { 213, 1}, { 214, 2}, { 216, 1}, { 217, 1}, { 218, 1}, { 219, 1}, { 220, 1}, { 221, 1}, { 222, 1}, { 223, 1},
|
||||
{ 224, 2}, { 226, 1}, { 227, 1}, { 228, 1}, { 229, 1}, { 230, 1}, { 231, 1}, { 232, 1}, { 233, 1}, { 234, 1}, { 235, 1}, { 236, 1}, { 237, 1}, { 238, 1}, { 239, 1}, { 240, 1},
|
||||
{ 241, 1}, { 242, 1}, { 243, 1}, { 244, 1}, { 245, 1}, { 246, 1}, { 247, 1}, { 248, 1}, { 249, 1}, { 250, 1}, { 251, 1}, { 252, 1}, { 253, 1}, { 254, 1}, { 255, 1}, { 256, 1},
|
||||
{ 257, 1}, { 258, 1}, { 259, 1}, { 260, 1}, { 261, 1}, { 262, 1}, { 263, 1}, { 264, 1}, { 265, 1}, { 266, 1}, { 267, 1}, { 268, 1}, { 269, 1}, { 270, 1}, { 271, 1}, { 272, 1},
|
||||
{ 273, 1}, { 274, 1}, { 275, 1}, { 276, 1}, { 277, 1}, { 278, 1}, { 279, 1}, { 280, 1}, { 281, 1}, { 282, 1},
|
||||
};
|
||||
u8 const Asm_riscv::raw_encode_forms[5943] = {
|
||||
0x01, 0x00, 0x01, 0x07, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x01, 0x07, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x01, 0x09, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x04,
|
||||
0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00, 0x67, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x05, 0x00, 0x01, 0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x06, 0x00, 0x01, 0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x07, 0x00,
|
||||
0x01, 0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x40, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x01, 0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x09, 0x00, 0x01, 0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x60, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0a, 0x00, 0x01,
|
||||
0x01, 0x08, 0x00, 0x02, 0x03, 0x09, 0x00, 0x63, 0x70, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x34, 0x0b, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0c, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0d, 0x00, 0x01, 0x0a,
|
||||
0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0e, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x40, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0f, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x01, 0x0a, 0x00,
|
||||
0x00, 0x03, 0x0d, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x23, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x12, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x23, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x13, 0x00, 0x01, 0x0a, 0x00, 0x00,
|
||||
0x01, 0x0c, 0x00, 0x00, 0x03, 0x60, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x22, 0x15, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x23, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x22, 0x16, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01,
|
||||
0x02, 0x07, 0x00, 0x13, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x17, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00, 0x13, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00, 0x13, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x19, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02,
|
||||
0x07, 0x00, 0x13, 0x40, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1a, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00, 0x13, 0x60, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1b, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00, 0x13, 0x70, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1c, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06,
|
||||
0x00, 0x13, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x1d, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x1e, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x50, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x1f, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x02, 0x07, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x01, 0x01, 0x05, 0x00, 0x01, 0x02, 0x05, 0x00, 0x1b, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x21, 0x00, 0x01, 0x01, 0x05, 0x00, 0x01, 0x02, 0x05, 0x00, 0x1b, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x22, 0x00, 0x01, 0x01, 0x05, 0x00, 0x01, 0x02, 0x05, 0x00, 0x1b,
|
||||
0x50, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x23, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x24, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x00, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x25, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10,
|
||||
0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x26, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x27, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x28, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x40, 0x00,
|
||||
0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x29, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x2a, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x2b, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x60, 0x00, 0x00,
|
||||
0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x2c, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x70, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x30, 0x2d, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x2e, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x40, 0x7f,
|
||||
0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x2f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x30, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xfe, 0x00, 0x00, 0x32, 0x31, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x50, 0x00, 0x40, 0x7f, 0x70,
|
||||
0x00, 0xfe, 0x00, 0x00, 0x32, 0x32, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x11, 0x12, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x10, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x04, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x10, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x04, 0x36, 0x00, 0x01, 0x0b, 0x01, 0x00, 0x01, 0x0f, 0x02, 0x00, 0x73, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x05, 0x00, 0x30, 0x37, 0x00, 0x01, 0x0b, 0x01, 0x00, 0x01, 0x0f, 0x02, 0x00, 0x73, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00,
|
||||
0x05, 0x00, 0x30, 0x38, 0x00, 0x01, 0x0b, 0x01, 0x00, 0x01, 0x0f, 0x02, 0x00, 0x73, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x05, 0x00, 0x30, 0x39, 0x00, 0x01, 0x0b, 0x0e, 0x00, 0x01, 0x0f, 0x10, 0x00, 0x73, 0x50, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x05, 0x00, 0x30, 0x3a, 0x00, 0x01, 0x0b, 0x0e, 0x00, 0x01, 0x0f, 0x10, 0x00, 0x73, 0x60, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x05,
|
||||
0x00, 0x30, 0x3b, 0x00, 0x01, 0x0b, 0x0e, 0x00, 0x01, 0x0f, 0x10, 0x00, 0x73, 0x70, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x05, 0x00, 0x30, 0x3c, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x00, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x3d, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00,
|
||||
0x30, 0x3e, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x20, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x3f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x30, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x40, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x40, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30,
|
||||
0x41, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x42, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x60, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x43, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x70, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x30, 0x44,
|
||||
0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x32, 0x45, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x40, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x32, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x50, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x32, 0x47, 0x00,
|
||||
0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x60, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x32, 0x48, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x70, 0x00, 0x02, 0x7f, 0x70, 0x00, 0xfe, 0x01, 0x00, 0x32, 0x49, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x2f, 0x20, 0x00, 0x10, 0x7f, 0x70, 0xf0, 0xf9, 0x02, 0x00, 0x20, 0x4a, 0x00, 0x01,
|
||||
0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x18, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x4b, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x08, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x4c, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x4d, 0x00, 0x01, 0x01,
|
||||
0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x4e, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x4f, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x50, 0x00, 0x01, 0x01, 0x0a,
|
||||
0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0x80, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x51, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0xa0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x52, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0xc0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x53, 0x00, 0x01, 0x01, 0x0a, 0x00,
|
||||
0x01, 0x03, 0x0e, 0x00, 0x2f, 0x20, 0x00, 0xe0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x30, 0x54, 0x00, 0x01, 0x0a, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x2f, 0x30, 0x00, 0x10, 0x7f, 0x70, 0xf0, 0xf9, 0x02, 0x00, 0x22, 0x55, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x18, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x56, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01,
|
||||
0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x08, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x57, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x58, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x59, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03,
|
||||
0x0e, 0x00, 0x2f, 0x30, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5a, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5b, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0x80, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5c, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e,
|
||||
0x00, 0x2f, 0x30, 0x00, 0xa0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5d, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0xc0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5e, 0x00, 0x01, 0x01, 0x0a, 0x00, 0x01, 0x03, 0x0e, 0x00, 0x2f, 0x30, 0x00, 0xe0, 0x7f, 0x70, 0x00, 0xf8, 0x02, 0x00, 0x32, 0x5f, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00,
|
||||
0x07, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x03, 0x00, 0x20, 0x60, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x27, 0x20, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x03, 0x00, 0x20, 0x61, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x43, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x48, 0x62, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x47,
|
||||
0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x48, 0x63, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4b, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x48, 0x64, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x48, 0x65, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00,
|
||||
0x00, 0x00, 0x7f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x38, 0x66, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x08, 0x7f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x38, 0x67, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x10, 0x7f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x38, 0x68, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00,
|
||||
0x18, 0x7f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x38, 0x69, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0x58, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x28, 0x6a, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x6b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x20,
|
||||
0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x6c, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x6d, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x28, 0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x6e, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x28, 0x7f,
|
||||
0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x6f, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x28, 0x70, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xc0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x28, 0x71, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xe0, 0x7f, 0x70,
|
||||
0xf0, 0xff, 0x03, 0x00, 0x20, 0x72, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0xa0, 0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x73, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0xa0, 0x7f, 0x70, 0x00, 0xfe, 0x03, 0x00, 0x30, 0x74, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0xa0, 0x7f, 0x70, 0x00,
|
||||
0xfe, 0x03, 0x00, 0x30, 0x75, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x10, 0x00, 0xe0, 0x7f, 0x70, 0xf0, 0xff, 0x03, 0x00, 0x20, 0x76, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xd0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x28, 0x77, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xd0, 0x7f, 0x00, 0xf0, 0xff,
|
||||
0x03, 0x00, 0x28, 0x78, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xf0, 0x7f, 0x70, 0xf0, 0xff, 0x03, 0x00, 0x20, 0x79, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0xc0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x2a, 0x7a, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xc0, 0x7f, 0x00, 0xf0, 0xff, 0x03,
|
||||
0x00, 0x2a, 0x7b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0xd0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x2a, 0x7c, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xd0, 0x7f, 0x00, 0xf0, 0xff, 0x03, 0x00, 0x2a, 0x7d, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x04, 0x00,
|
||||
0x20, 0x7e, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x27, 0x30, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x04, 0x00, 0x20, 0x7f, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x43, 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x06, 0x04, 0x00, 0x48, 0x80, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x47, 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x06, 0x04, 0x00, 0x48,
|
||||
0x81, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4b, 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x06, 0x04, 0x00, 0x48, 0x82, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4f, 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0x06, 0x04, 0x00, 0x48, 0x83, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x02, 0x7f, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x38, 0x84,
|
||||
0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x0a, 0x7f, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x38, 0x85, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x12, 0x7f, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x38, 0x86, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x1a, 0x7f, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x38, 0x87, 0x00,
|
||||
0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0x5a, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x88, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x22, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x89, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x22, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x8a, 0x00, 0x02,
|
||||
0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0x22, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x8b, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x2a, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x8c, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x2a, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x8d, 0x00, 0x02, 0x02,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0x40, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x8e, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0x42, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x8f, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0xa2, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x90, 0x00, 0x01, 0x02, 0x02,
|
||||
0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0xa2, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x91, 0x00, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0xa2, 0x7f, 0x70, 0x00, 0xfe, 0x04, 0x00, 0x30, 0x92, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x10, 0x00, 0xe2, 0x7f, 0x70, 0xf0, 0xff, 0x04, 0x00, 0x20, 0x93, 0x00, 0x01, 0x02, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xc2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x94, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xc2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x95, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xd2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x96, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01,
|
||||
0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xd2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x28, 0x97, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0xc2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x2a, 0x98, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xc2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x2a, 0x99, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02,
|
||||
0x00, 0x00, 0x53, 0x00, 0x20, 0xd2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x2a, 0x9a, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xd2, 0x7f, 0x00, 0xf0, 0xff, 0x04, 0x00, 0x2a, 0x9b, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xe2, 0x7f, 0x70, 0xf0, 0xff, 0x04, 0x00, 0x22, 0x9c, 0x00, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00,
|
||||
0x00, 0x53, 0x00, 0x00, 0xf2, 0x7f, 0x70, 0xf0, 0xff, 0x04, 0x00, 0x22, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x00, 0x00, 0x9f, 0x00, 0x0f, 0x10, 0x15, 0x00, 0x17, 0x00, 0x1d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0xa0, 0xa0, 0x00, 0x0f, 0x1a, 0x00, 0x00, 0x17, 0x26, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xa1, 0x00, 0x0f, 0x1b, 0x00, 0x00, 0x17, 0x27, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x22, 0xa2, 0x00, 0x0f, 0x1a, 0x00, 0x00, 0x19, 0x26, 0x00, 0x00, 0x00,
|
||||
0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xa3, 0x00, 0x0f, 0x1b, 0x00, 0x00, 0x19, 0x27, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x22, 0xa4, 0x00, 0x12, 0x1a, 0x00, 0x00, 0x17, 0x26, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x21, 0xa5, 0x00, 0x12, 0x1a, 0x00, 0x00, 0x19, 0x26, 0x00, 0x00, 0x00, 0xe0,
|
||||
0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x21, 0xa6, 0x00, 0x12, 0x1b, 0x00, 0x00, 0x17, 0x27, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x04, 0x00, 0x20, 0xa7, 0x00, 0x12, 0x1b, 0x00, 0x00, 0x19, 0x27, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x04, 0x00, 0x20, 0xa8, 0x00, 0x11, 0x13, 0x00, 0x00, 0x15, 0x1b, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xa9, 0x00, 0x11, 0x13, 0x00, 0x00, 0x15, 0x1b, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x22, 0xaa, 0x00, 0x11, 0x13, 0x00, 0x00, 0x15, 0x1b, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xab, 0x00, 0x11, 0x17, 0x00, 0x00, 0x15, 0x1e, 0x00, 0x00, 0x01, 0x60, 0x00, 0x00,
|
||||
0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xac, 0x00, 0x10, 0x16, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x61, 0x00, 0x00, 0x83, 0xef, 0x00, 0x00, 0x07, 0x00, 0x90, 0xad, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x1a, 0x1c, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x07, 0x00, 0x20, 0xae, 0x00, 0x0f, 0x14, 0x00, 0x00, 0x1a, 0x1c, 0x00, 0x00, 0x01, 0x84, 0x00, 0x00, 0x03,
|
||||
0xec, 0x00, 0x00, 0x07, 0x00, 0x20, 0xaf, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x1a, 0x1b, 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x07, 0x00, 0x20, 0xb0, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x63, 0xfc, 0x00, 0x00, 0x07, 0x00, 0x20, 0xb1, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x21, 0x8c, 0x00, 0x00, 0x63, 0xfc,
|
||||
0x00, 0x00, 0x07, 0x00, 0x20, 0xb2, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x41, 0x8c, 0x00, 0x00, 0x63, 0xfc, 0x00, 0x00, 0x07, 0x00, 0x20, 0xb3, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x61, 0x8c, 0x00, 0x00, 0x63, 0xfc, 0x00, 0x00, 0x07, 0x00, 0x20, 0xb4, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x01, 0x9c, 0x00, 0x00, 0x63, 0xfc, 0x00,
|
||||
0x00, 0x07, 0x00, 0x22, 0xb5, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x1a, 0x19, 0x00, 0x00, 0x21, 0x9c, 0x00, 0x00, 0x63, 0xfc, 0x00, 0x00, 0x07, 0x00, 0x22, 0xb6, 0x00, 0x19, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0xa0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x14, 0xb7, 0x00, 0x19, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00,
|
||||
0x07, 0x00, 0x15, 0xb8, 0x00, 0x0f, 0x18, 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x24, 0xb9, 0x00, 0x0f, 0x18, 0x00, 0x00, 0x18, 0x24, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x24, 0xba, 0x00, 0x11, 0x14, 0x00, 0x00, 0x15, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07,
|
||||
0x00, 0x20, 0xbb, 0x00, 0x11, 0x1c, 0x00, 0x00, 0x15, 0x28, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xbc, 0x00, 0x11, 0x1d, 0x00, 0x00, 0x15, 0x29, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x22, 0xbd, 0x00, 0x01, 0x1c, 0x00, 0x00, 0x16, 0x20, 0x00, 0x00, 0x02, 0xc0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00,
|
||||
0x20, 0xbe, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x16, 0x21, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x22, 0xbf, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x15, 0x29, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x04, 0x00, 0x20, 0xc0, 0x00, 0x02, 0x1d, 0x00, 0x00, 0x16, 0x21, 0x00, 0x00, 0x02, 0xa0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x04, 0x00, 0x20,
|
||||
0xc1, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x14, 0xc2, 0x00, 0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x14, 0xc3, 0x00, 0x11, 0x11, 0x00, 0x00, 0x15, 0x16, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xc4,
|
||||
0x00, 0x11, 0x11, 0x00, 0x00, 0x15, 0x16, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x07, 0x00, 0x20, 0xc5, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x15, 0x28, 0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x21, 0xc6, 0x00, 0x02, 0x1c, 0x00, 0x00, 0x16, 0x20, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x03, 0x00, 0x21, 0xc7, 0x00,
|
||||
0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x20, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x30, 0xc8, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x40, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x30, 0xc9, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x60, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x30, 0xca, 0x00, 0x01,
|
||||
0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x08, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x32, 0xcb, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x20, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x32, 0xcc, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x40, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x32, 0xcd, 0x00, 0x01, 0x01,
|
||||
0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x60, 0x00, 0x20, 0x7f, 0x70, 0x00, 0xfe, 0x08, 0x00, 0x32, 0xce, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x1b, 0x10, 0x00, 0x08, 0x7f, 0x70, 0x00, 0xfc, 0x08, 0x00, 0x32, 0xcf, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x70, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xd0, 0x00, 0x01, 0x01, 0x01,
|
||||
0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x60, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xd1, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x40, 0x00, 0x40, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xd2, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13, 0x10, 0x00, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xd3, 0x00, 0x01, 0x01, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x00, 0x13, 0x10, 0x10, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xd4, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13, 0x10, 0x20, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xd5, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13, 0x10, 0x40, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xd6, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
|
||||
0x02, 0x00, 0x00, 0x13, 0x10, 0x50, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xd7, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x33, 0x40, 0x00, 0x08, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x21, 0xd7, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x3b, 0x40, 0x00, 0x08, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x22, 0xd8, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02,
|
||||
0x03, 0x00, 0x33, 0x40, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xd9, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xda, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x60, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xdb, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03,
|
||||
0x00, 0x33, 0x70, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xdc, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xdd, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x30, 0xde, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00,
|
||||
0x13, 0x50, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xfc, 0x09, 0x00, 0x30, 0xdf, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13, 0x50, 0x70, 0x28, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x20, 0xe0, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13, 0x50, 0x80, 0x69, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x21, 0xe0, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x13,
|
||||
0x50, 0x80, 0x6b, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x22, 0xe1, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x1b, 0x10, 0x00, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x22, 0xe2, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x1b, 0x10, 0x10, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x22, 0xe3, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x1b, 0x10,
|
||||
0x20, 0x60, 0x7f, 0x70, 0xf0, 0xff, 0x09, 0x00, 0x22, 0xe4, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x10, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x32, 0xe5, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x3b, 0x50, 0x00, 0x60, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x32, 0xe6, 0x00, 0x01, 0x01, 0x05, 0x00, 0x01, 0x02, 0x05, 0x00, 0x1b, 0x50, 0x00,
|
||||
0x60, 0x7f, 0x70, 0x00, 0xfe, 0x09, 0x00, 0x32, 0xe7, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x0a, 0x00, 0x30, 0xe8, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x30, 0x00, 0x0a, 0x7f, 0x70, 0x00, 0xfe, 0x0a, 0x00, 0x30, 0xe9, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x20, 0x00, 0x0a,
|
||||
0x7f, 0x70, 0x00, 0xfe, 0x0a, 0x00, 0x30, 0xea, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x48, 0x7f, 0x70, 0x00, 0xfe, 0x0b, 0x00, 0x30, 0xeb, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x10, 0x00, 0x48, 0x7f, 0x70, 0x00, 0xfc, 0x0b, 0x00, 0x30, 0xec, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x48, 0x7f,
|
||||
0x70, 0x00, 0xfe, 0x0b, 0x00, 0x30, 0xed, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x50, 0x00, 0x48, 0x7f, 0x70, 0x00, 0xfc, 0x0b, 0x00, 0x30, 0xee, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x68, 0x7f, 0x70, 0x00, 0xfe, 0x0b, 0x00, 0x30, 0xef, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x10, 0x00, 0x68, 0x7f, 0x70,
|
||||
0x00, 0xfc, 0x0b, 0x00, 0x30, 0xf0, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x10, 0x00, 0x28, 0x7f, 0x70, 0x00, 0xfe, 0x0b, 0x00, 0x30, 0xf1, 0x00, 0x01, 0x01, 0x06, 0x00, 0x01, 0x02, 0x06, 0x00, 0x13, 0x10, 0x00, 0x28, 0x7f, 0x70, 0x00, 0xfc, 0x0b, 0x00, 0x30, 0xf2, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x50, 0x00, 0x0e, 0x7f, 0x70, 0x00,
|
||||
0xfe, 0x0c, 0x00, 0x30, 0xf3, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x02, 0x03, 0x00, 0x33, 0x70, 0x00, 0x0e, 0x7f, 0x70, 0x00, 0xfe, 0x0c, 0x00, 0x30, 0xf4, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00, 0x0d, 0x00, 0x20, 0xf5, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x03, 0x0d, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x7f, 0x70, 0x00, 0x00,
|
||||
0x0d, 0x00, 0x20, 0xf6, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x43, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x06, 0x0d, 0x00, 0x48, 0xf7, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x47, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x06, 0x0d, 0x00, 0x48, 0xf8, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4b, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x06, 0x0d,
|
||||
0x00, 0x48, 0xf9, 0x00, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x03, 0x04, 0x4f, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0x06, 0x0d, 0x00, 0x48, 0xfa, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x04, 0x7f, 0x00, 0x00, 0xfe, 0x0d, 0x00, 0x38, 0xfb, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x0c, 0x7f, 0x00, 0x00, 0xfe, 0x0d, 0x00,
|
||||
0x38, 0xfc, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x14, 0x7f, 0x00, 0x00, 0xfe, 0x0d, 0x00, 0x38, 0xfd, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x1c, 0x7f, 0x00, 0x00, 0xfe, 0x0d, 0x00, 0x38, 0xfe, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0x5c, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28,
|
||||
0xff, 0x00, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x24, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x00, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x24, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0x24, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x02,
|
||||
0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0x2c, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x03, 0x01, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0x2c, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x04, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xc4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x05, 0x01,
|
||||
0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xc4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x06, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0xc4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x2a, 0x07, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xc4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x2a, 0x08, 0x01, 0x02,
|
||||
0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xd4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x09, 0x01, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0xd4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x0a, 0x01, 0x02, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0xd4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x2a, 0x0b, 0x01, 0x02, 0x01,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x30, 0xd4, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x2a, 0x0c, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0x40, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x0d, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0x44, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x0e, 0x01, 0x02, 0x02, 0x00,
|
||||
0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x20, 0x42, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x0f, 0x01, 0x02, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x10, 0x44, 0x7f, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0x28, 0x10, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xe4, 0x7f, 0x70, 0xf0, 0xff, 0x0d, 0x00, 0x20, 0x11, 0x01, 0x02, 0x01, 0x00, 0x00,
|
||||
0x01, 0x02, 0x00, 0x00, 0x53, 0x00, 0x00, 0xf4, 0x7f, 0x70, 0xf0, 0xff, 0x0d, 0x00, 0x20, 0x12, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x53, 0x10, 0x00, 0xe4, 0x7f, 0x70, 0xf0, 0xff, 0x0d, 0x00, 0x20, 0x13, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x20, 0x00, 0xa4, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x14, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01,
|
||||
0x02, 0x03, 0x00, 0x53, 0x10, 0x00, 0xa4, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x15, 0x01, 0x01, 0x02, 0x02, 0x00, 0x01, 0x02, 0x03, 0x00, 0x53, 0x00, 0x00, 0xa4, 0x7f, 0x70, 0x00, 0xfe, 0x0d, 0x00, 0x30, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x20, 0x30, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x04, 0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x73, 0x00, 0x20, 0x10, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x04, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x50, 0x10, 0xff, 0xff, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x19, 0x01, 0x01, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x00, 0x73, 0x00, 0x00, 0x12, 0xff, 0x7f, 0x00, 0xfe, 0x0e, 0x00, 0x20,
|
||||
};
|
||||
u8 const Asm_riscv::raw_clobber_forms[2547] = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x01, 0x06, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x1d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
|
||||
};
|
||||
u8 const Asm_riscv::raw_pseudo_aliases[696] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x04, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x19, 0x00, 0x01, 0x02, 0x06, 0x00, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, 0x24, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2e, 0x00, 0x01, 0x04,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x01, 0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x01, 0x02, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x02, 0x00, 0x18, 0x00, 0x01, 0x02, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x26, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x07, 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x09, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x02, 0x01,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x05, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x36, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x38, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x39, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x3a, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x01, 0x00, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x01, 0x00, 0x37, 0x00, 0x01, 0x07,
|
||||
0x04, 0x00, 0x00, 0x00, 0x80, 0x0c, 0x01, 0x01, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x81, 0x0c, 0x01, 0x01, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x82, 0x0c, 0x01, 0x01, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x36, 0x00, 0x01, 0x07, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x02, 0x00, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x01, 0x00, 0x36, 0x00, 0x01, 0x07, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x37, 0x00, 0x01, 0x07, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x36, 0x00, 0x01, 0x07, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x39, 0x00, 0x01, 0x07, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x39, 0x00, 0x01, 0x07, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
|
||||
0x6a, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x6b, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x88, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x89, 0x00, 0x01, 0x02,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0x00, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x32, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
@@ -312,15 +312,32 @@ gb_internal bool check_asm_operand_size_class(AsmCtx *asm_ctx, typename AsmCtx::
|
||||
// Width check.
|
||||
if (want_w != 0 && got_w != 0) {
|
||||
if (want_class == AsmRegClass_Vector && !is_memory) {
|
||||
// A scalar float uses only the low lane, so it is valid in any vector
|
||||
// register slot as long as it fits; a #simd vector must match exactly.
|
||||
// A scalar float uses only the low lane, so it may be narrower than the
|
||||
// slot; a #simd vector must match the vector width exactly.
|
||||
bool width_ok = (got_class == AsmRegClass_Float) ? (got_w <= want_w) : (got_w == want_w);
|
||||
if (!width_ok) {
|
||||
if (mismatch_) *mismatch_ = AsmMismatch_Size;
|
||||
return false;
|
||||
}
|
||||
} else if (want_class == AsmRegClass_Float &&
|
||||
got_class == AsmRegClass_Float && !is_memory &&
|
||||
!asm_ctx->float_reg_width_is_exact()) {
|
||||
// NOTE(bill): architectures such as RISC-V have registers which are
|
||||
// always the architecture width
|
||||
if (got_w > want_w) {
|
||||
if (mismatch_) *mismatch_ = AsmMismatch_Size;
|
||||
return false;
|
||||
}
|
||||
} else if (want_class == AsmRegClass_Integer && !is_memory &&
|
||||
!asm_ctx->integer_reg_width_is_exact()) {
|
||||
// NOTE(bill): architectures such as RISC-V have registers which are
|
||||
// always the architecture width
|
||||
if (got_w > want_w) {
|
||||
if (mismatch_) *mismatch_ = AsmMismatch_Size;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Integer/mask registers, and all memory operands: exact width.
|
||||
// Integer/mask registers on exact-width targets, and all memory operands.
|
||||
if (want_w != got_w) {
|
||||
if (mismatch_) *mismatch_ = AsmMismatch_Size;
|
||||
return false;
|
||||
@@ -489,6 +506,14 @@ gb_internal AsmTemplateEntityDeclKind check_asm_find_kind(Entity *entity, Array<
|
||||
return AsmTemplateEntityDecl_Invalid;
|
||||
};
|
||||
|
||||
gb_internal bool check_asm_is_immediate_param(Entity *tmpl_entity, Operand const *o) {
|
||||
Entity *pe = entity_of_node(o->expr);
|
||||
if (pe != nullptr && pe->kind == Entity_Variable) {
|
||||
return check_asm_find_kind(pe, tmpl_entity->AsmTemplate.decls) == AsmTemplateEntityDecl_Immediate;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename AsmCtx>
|
||||
gb_internal void check_asm_specs(AsmCtx *asm_ctx, CheckerContext *ctx, Scope *scope, Slice<Ast *> const &specs, Array<AsmTemplateEntityDecl> *asm_template_entity_decls) {
|
||||
@@ -647,6 +672,10 @@ gb_internal void check_asm_specs(AsmCtx *asm_ctx, CheckerContext *ctx, Scope *sc
|
||||
}
|
||||
}
|
||||
|
||||
if (other_scratch == nullptr && check_asm_reg_class_from_type(type) != AsmRegClass_Unknown) {
|
||||
ed.kind = AsmTemplateEntityDecl_Register;
|
||||
}
|
||||
|
||||
array_add(asm_template_entity_decls, ed);
|
||||
} else {
|
||||
TokenPos pos = found->token.pos;
|
||||
@@ -844,11 +873,84 @@ gb_internal bool check_register(AsmCtx *asm_ctx, Operand *operand, AstAsmRegiste
|
||||
enum CheckMnemomicResult {
|
||||
CheckMnemomic_Invalid,
|
||||
CheckMnemomic_Mnemonic,
|
||||
CheckMnemomic_PseudoMnemonic,
|
||||
CheckMnemomic_PseudoMacroMnemonic,
|
||||
CheckMnemomic_Prefix,
|
||||
};
|
||||
|
||||
template <typename AsmCtx>
|
||||
gb_internal CheckMnemomicResult check_mnemonic_name(AsmCtx *asm_ctx, AstAsmInstruction *instr, u16 *mnemonic_) {
|
||||
gb_internal bool check_pseudo_macro_mnemonic(AsmCtx *asm_ctx, Entity *tmpl_entity,
|
||||
AstAsmInstruction *instr, Slice<Operand> const &operands) {
|
||||
if (build_context.metrics.arch != TargetArch_riscv64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE(bill): this is probably not even a complete list when it comes to
|
||||
of the pseudo macro mnemonics, but this currently covers most of them.
|
||||
It just handles those edge cases directly as the LLVM assembler will
|
||||
handle them directly any way.
|
||||
*/
|
||||
|
||||
int const XLEN = cast(int)(build_context.metrics.ptr_size*8);
|
||||
|
||||
String name = instr->name->Ident.token.string;
|
||||
|
||||
auto want_int_reg = [&](Operand const *o, char const *role) {
|
||||
if (determine_asm_operand_kind(o) != AsmOperand_Register ||
|
||||
check_asm_reg_class_from_type(o->type) != AsmRegClass_Integer) {
|
||||
error(o->expr, "'%.*s' %s must be an integer register", LIT(name), role);
|
||||
return false;
|
||||
}
|
||||
int width = check_asm_operand_bit_width(o->type);
|
||||
if (width > XLEN) {
|
||||
error(o->expr, "'%.*s' %s is wider than the %d-bit register width, got %d-bits", LIT(name), role, XLEN, width);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (name == "li") { // li rd, imm — dest reg + assemble-time integer that fits XLEN (or a $-immediate)
|
||||
if (operands.count != 2) {
|
||||
error(instr->name, "'%.*s' expects 2 operands, got %td", LIT(name), operands.count);
|
||||
return true; // it exists but incorrectly handled
|
||||
}
|
||||
want_int_reg(&operands[0], "destination");
|
||||
Operand const *imm = &operands[1];
|
||||
if (imm->mode == Addressing_Constant) {
|
||||
ExactValue ev = exact_value_to_integer(imm->value);
|
||||
if (ev.kind != ExactValue_Integer) {
|
||||
error(imm->expr, "'%.*s' immediate must be an integer constant", LIT(name));
|
||||
return true;
|
||||
}
|
||||
AsmMismatch m = AsmMismatch_None; i32 needed = 0;
|
||||
if (!check_asm_immediate_value_fits(ev, XLEN, &needed, &m)) {
|
||||
gbString vs = exact_value_to_string(ev);
|
||||
error(imm->expr, "'%.*s' immediate %s does not fit in a %d-bit register (needs %d bits)", LIT(name), vs, XLEN, needed);
|
||||
gb_string_free(vs);
|
||||
}
|
||||
} else if (!check_asm_is_immediate_param(tmpl_entity, imm)) {
|
||||
error(imm->expr, "'li' source must be a constant integer or a $ immediate parameter");
|
||||
}
|
||||
return true;
|
||||
} else if (name == "la" || name == "lla") { // la / lla rd, symbol — dest reg + a label (or symbol, once representable)
|
||||
if (operands.count != 2) {
|
||||
error(instr->name, "'%.*s' expects 2 operands, got %td", LIT(name), operands.count);
|
||||
// NOTE(bill): it exists but incorrectly handled
|
||||
return true;
|
||||
}
|
||||
want_int_reg(&operands[0], "destination");
|
||||
if (determine_asm_operand_kind(&operands[1]) != AsmOperand_Label) {
|
||||
error(operands[1].expr, "'%.*s' source must be a label", LIT(name));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename AsmCtx>
|
||||
gb_internal CheckMnemomicResult check_mnemonic_name(AsmCtx *asm_ctx, AstAsmInstruction *instr, u16 *mnemonic_, u8 *suffix_flags_) {
|
||||
Token token = instr->name->Ident.token;
|
||||
GB_ASSERT_MSG(token.kind == Token_Ident || token_is_keyword(token.kind), "got %.*s of kind %.*s", LIT(token.string), LIT(token_strings[token.kind]));
|
||||
String name = token.string;
|
||||
@@ -862,6 +964,25 @@ gb_internal CheckMnemomicResult check_mnemonic_name(AsmCtx *asm_ctx, AstAsmInstr
|
||||
if (mnemonic_) *mnemonic_ = cast(u16)m;
|
||||
return CheckMnemomic_Mnemonic;
|
||||
}
|
||||
auto pm = asm_ctx->pseudo_mnemonic_lookup(name);
|
||||
if (pm) {
|
||||
if (mnemonic_) *mnemonic_ = pm;
|
||||
return CheckMnemomic_PseudoMnemonic;
|
||||
}
|
||||
|
||||
u8 suffix_flags = 0;
|
||||
auto om = asm_ctx->mnemonic_lookup_ordered(name, &suffix_flags);
|
||||
if (om) {
|
||||
if (mnemonic_) *mnemonic_ = cast(u16)om;
|
||||
if (suffix_flags_) *suffix_flags_ = suffix_flags;
|
||||
return CheckMnemomic_Mnemonic;
|
||||
}
|
||||
|
||||
auto pmm = asm_ctx->pseudo_macro_mnemonic_lookup(name);
|
||||
if (pmm) {
|
||||
if (mnemonic_) *mnemonic_ = cast(u16)pmm;
|
||||
return CheckMnemomic_PseudoMacroMnemonic;
|
||||
}
|
||||
|
||||
ERROR_BLOCK();
|
||||
if (instr->operands.count == 0) {
|
||||
@@ -905,21 +1026,64 @@ struct AsmMnemonicAccumulator {
|
||||
u16 explicitly_produced_regs;
|
||||
u16 stale_outputs;
|
||||
|
||||
// #align_stack relevance: any call/branch (CONTROL) or memory effect that could
|
||||
// require the stack to be realigned. If none occurred, #align_stack is redundant.
|
||||
// Related to #align_stack
|
||||
// any call/branch (CONTROL) or memory effect that could require the stack
|
||||
// to be realigned. If none occurred, #align_stack is redundant.
|
||||
bool saw_call_or_mem;
|
||||
};
|
||||
|
||||
|
||||
template <typename AsmCtx>
|
||||
gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tmpl_entity, AstAsmInstruction *instr,
|
||||
u16 mnemonic, Slice<Operand> const &operands,
|
||||
u16 mnemonic, u16 pseudo_mnemonic, Slice<Operand> const &operands,
|
||||
u8 previous_prefix, Ast *previous_prefix_instr,
|
||||
AsmMnemonicAccumulator *asm_acc) {
|
||||
GB_ASSERT(mnemonic > 0);
|
||||
auto forms = asm_ctx->encoding_forms(mnemonic);
|
||||
String name = asm_ctx->mnemonic_strings[mnemonic];
|
||||
|
||||
auto alias = asm_ctx->pseudo_alias(cast(u16)pseudo_mnemonic);
|
||||
if (pseudo_mnemonic) {
|
||||
name = asm_ctx->pseudo_mnemonic_strings[pseudo_mnemonic];
|
||||
}
|
||||
|
||||
bool is_pseudo = pseudo_mnemonic != 0;
|
||||
int target_explicit_count = is_pseudo ? alias.nargs : -1;
|
||||
|
||||
|
||||
auto pseudo_alias_arg_operand_index = [](AsmCtx *asm_ctx, auto a, int arg_index) -> int {
|
||||
if (arg_index < 0 || arg_index > 2) {
|
||||
return -1;
|
||||
}
|
||||
auto want = cast(typename AsmCtx::AliasSrc)(asm_ctx->AliasSrc_ARG0 + arg_index);
|
||||
for (int i = 0; i < gb_count_of(a.src); i++) {
|
||||
if (a.src[i] == want) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
auto user_operand_target_index = [&](int user_i) -> int {
|
||||
if (!is_pseudo) {
|
||||
return user_i;
|
||||
}
|
||||
return pseudo_alias_arg_operand_index(asm_ctx, alias, user_i);
|
||||
};
|
||||
|
||||
auto operand_slot_type = [&](typename AsmCtx::Encoding const &form, int user_index) -> typename AsmCtx::OperandType {
|
||||
int raw_slot = -1;
|
||||
if (is_pseudo) {
|
||||
raw_slot = user_operand_target_index(user_index);
|
||||
} else {
|
||||
raw_slot = asm_ctx->form_explicit_slot(form, user_index);
|
||||
}
|
||||
if (0 <= raw_slot && raw_slot < cast(int)gb_count_of(form.ops)) {
|
||||
return form.ops[raw_slot];
|
||||
}
|
||||
return asm_ctx->OP_NONE;
|
||||
};
|
||||
|
||||
int min_count = I32_MAX;
|
||||
int max_count = -1;
|
||||
|
||||
@@ -931,6 +1095,11 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
min_count = gb_max(min_count, 0);
|
||||
max_count = gb_max(max_count, 0);
|
||||
|
||||
if (is_pseudo) {
|
||||
min_count = gb_min(min_count, target_explicit_count);
|
||||
max_count = gb_min(max_count, target_explicit_count);
|
||||
}
|
||||
|
||||
// A prefix that none of this mnemonic's forms can take is unconditionally wrong,
|
||||
// independent of whether the operands match — catch it even on a match failure.
|
||||
if (previous_prefix > 0) {
|
||||
@@ -948,7 +1117,6 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto valid_spots = slice_make<bool>(heap_allocator(), max_count);
|
||||
defer (slice_free(&valid_spots, heap_allocator()));
|
||||
|
||||
@@ -968,8 +1136,15 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
|
||||
for_array(form_index, forms) {
|
||||
auto &form = forms[form_index];
|
||||
if (operands.count != cast(int)form.explicit_count()) {
|
||||
continue;
|
||||
|
||||
if (is_pseudo) {
|
||||
if (cast(int)form.explicit_count() < target_explicit_count) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (operands.count != cast(int)form.explicit_count()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int score = 0;
|
||||
@@ -977,8 +1152,7 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
int width_pref = 0;
|
||||
|
||||
for_array(i, operands) {
|
||||
int slot = asm_ctx->form_explicit_slot(form, cast(int)i);
|
||||
auto type = (slot >= 0) ? form.ops[slot] : asm_ctx->OP_NONE;
|
||||
auto type = operand_slot_type(form, cast(int)i);
|
||||
Operand const *operand = &operands[i];
|
||||
AsmOperandKind dst = asm_ctx->kind_from_operand_type(type);
|
||||
AsmOperandKind src = determine_asm_operand_kind(operand);
|
||||
@@ -1080,8 +1254,7 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
// aligned at the call boundary) or manipulates RSP directly. Plain memory access
|
||||
// through a parameter pointer does NOT require stack realignment, so
|
||||
// implies_clobber_memory() is intentionally NOT used here.
|
||||
if ((cast(u16)clobber.side_effects & asm_ctx->SideEffectFlag_CONTROL) != 0 ||
|
||||
(cast(u16)clobber.implicit_wr & asm_ctx->ClobberReg_RSP) != 0) {
|
||||
if (clobber.is_call_or_mem()) {
|
||||
asm_acc->saw_call_or_mem = true;
|
||||
}
|
||||
|
||||
@@ -1122,7 +1295,8 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
// don't tell us which physical register was written.
|
||||
u16 written_ops = cast(u16)clobber.written;
|
||||
for_array(i, operands) {
|
||||
if (i >= 4 || (written_ops & (1u << i)) == 0) {
|
||||
int tslot = user_operand_target_index(cast(int)i);
|
||||
if (tslot < 0 || tslot >= 4 || (written_ops & (1u << tslot)) == 0) {
|
||||
continue;
|
||||
}
|
||||
Ast *e = operands[i].expr;
|
||||
@@ -1132,6 +1306,22 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
explicit_writes |= b;
|
||||
}
|
||||
}
|
||||
if (is_pseudo) {
|
||||
// Synthesized register sources (e.g. ra in `jal off` -> `jal ra, off`) also
|
||||
// write a physical register; record them so ra is treated as produced/clobbered.
|
||||
u16 synth = 0;
|
||||
for (int i = 0; i < gb_count_of(alias.src); i++) {
|
||||
if ((written_ops & (1u << i)) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (alias.src[i] == asm_ctx->AliasSrc_LINK) {
|
||||
GB_ASSERT(build_context.metrics.arch == TargetArch_riscv64);
|
||||
synth |= 1<<0; // ClobberReg_RA
|
||||
}
|
||||
}
|
||||
produced |= synth;
|
||||
explicit_writes |= synth;
|
||||
}
|
||||
asm_acc->defined_regs |= produced;
|
||||
|
||||
// Registers this form clobbers implicitly (RDTSC->RAX:RDX, etc.), for the
|
||||
@@ -1159,17 +1349,16 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
// is not merely CONTROL-with-fallthrough. We approximate "unconditional" as
|
||||
// CONTROL|HALT with no explicit label/operand fallthrough below.
|
||||
{
|
||||
u16 se = cast(u16)clobber.side_effects;
|
||||
bool control = (se & asm_ctx->SideEffectFlag_CONTROL) != 0;
|
||||
bool halt = (se & asm_ctx->SideEffectFlag_HALT) != 0;
|
||||
bool control = clobber.has_control();
|
||||
bool halt = clobber.has_halt();
|
||||
// A conditional branch reads a flag and can fall through -> not terminal.
|
||||
bool conditional = control && (cast(u16)clobber.flags_rd != 0);
|
||||
bool conditional = clobber.is_conditional();
|
||||
asm_acc->last_is_terminal = halt || (control && !conditional);
|
||||
}
|
||||
|
||||
// A branch/call inside the template means subsequent instructions may be reached
|
||||
// out of textual order; stop trusting the linear def model past this point.
|
||||
if (cast(u16)clobber.side_effects & asm_ctx->SideEffectFlag_CONTROL) {
|
||||
if (clobber.has_control()) {
|
||||
asm_acc->straight_line = false;
|
||||
}
|
||||
asm_ctx->clobber_implicit_regs(&tmpl_entity->AsmTemplate.clobber_registers_set, produced);
|
||||
@@ -1185,8 +1374,7 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
if (best_form >= 0) {
|
||||
auto &form = forms[best_form];
|
||||
for_array(i, operands) {
|
||||
int slot = asm_ctx->form_explicit_slot(form, cast(int)i);
|
||||
auto type = (slot >= 0) ? form.ops[slot] : asm_ctx->OP_NONE;
|
||||
auto type = operand_slot_type(form, cast(int)i);
|
||||
AsmOperandKind dst = asm_ctx->kind_from_operand_type(type);
|
||||
AsmOperandKind src = determine_asm_operand_kind(&operands[i]);
|
||||
possible_kinds[i] = dst;
|
||||
@@ -1246,8 +1434,10 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
error(operands[i].expr, "'%.*s' operand-%td: a floating-point constant cannot be used as an immediate",
|
||||
LIT(name), i);
|
||||
} else if (m == AsmMismatch_Size && want_bits[i] && got_bits[i]) {
|
||||
error(operands[i].expr, "'%.*s' operand-%td has the wrong size: expected a %u-bit operand, got %u-bit",
|
||||
LIT(name), i, cast(unsigned)want_bits[i], cast(unsigned)got_bits[i]);
|
||||
error(operands[i].expr, "'%.*s' operand-%td has the wrong size: expected a %u-bit %.*s operand, got %u-bit",
|
||||
LIT(name), i,
|
||||
cast(unsigned)want_bits[i], LIT(asm_reg_class_strings[dst_reg_class]),
|
||||
cast(unsigned)got_bits[i]);
|
||||
} else if (m == AsmMismatch_Class) {
|
||||
error(operands[i].expr, "'%.*s' operand-%td is in the wrong register class, expected %d-bit %.*s %.*s, got %d-bit %.*s %.*s",
|
||||
LIT(name), i,
|
||||
@@ -1256,7 +1446,7 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm
|
||||
} else if (dst == AsmOperand_Immediate) {
|
||||
error(operands[i].expr, "'%.*s' operand-%td must be an assemble-time constant or a $ immediate parameter, got a %.*s",
|
||||
LIT(name), i, LIT(asm_operand_kind_strings[src]));
|
||||
}else if (dst) {
|
||||
} else if (dst) {
|
||||
error(operands[i].expr, "'%.*s' operand-%td has an invalid kind, expected %.*s operand",
|
||||
LIT(name), i, LIT(asm_operand_kind_expected_strings[dst]));
|
||||
} else {
|
||||
@@ -1286,6 +1476,13 @@ gb_internal void check_asm_instruction_operand(AsmCtx *asm_ctx, CheckerContext *
|
||||
gb_unused(label_scope);
|
||||
|
||||
switch (expr->kind) {
|
||||
case_ast_node(ue, UnaryExpr, expr);
|
||||
check_expr(ctx, operand, expr);
|
||||
if (operand->mode != Addressing_Constant) {
|
||||
error(expr, "Asm operands within unary operands (+ - ~) can only compile time constants");
|
||||
}
|
||||
return;
|
||||
case_end;
|
||||
case_ast_node(pe, ParenExpr, expr);
|
||||
check_expr(ctx, operand, expr);
|
||||
if (operand->mode != Addressing_Constant) {
|
||||
@@ -1600,6 +1797,17 @@ gb_internal void check_asm_instruction_operand(AsmCtx *asm_ctx, CheckerContext *
|
||||
gb_string_free(s);
|
||||
}
|
||||
|
||||
if (index.expr != nullptr) {
|
||||
if (!asm_ctx->supports_memory_index_not_just_disp()) {
|
||||
error(index.expr, "The target platform does not support memory indexing within memory operands, only displacements");
|
||||
}
|
||||
}
|
||||
if (scale.expr != nullptr) {
|
||||
if (!asm_ctx->supports_memory_index_not_just_disp()) {
|
||||
error(scale.expr, "The target platform does not support memory index scaling within memory operands");
|
||||
}
|
||||
}
|
||||
|
||||
if (mem_op->type) {
|
||||
Type *t = check_type(ctx, mem_op->type);
|
||||
if (t != nullptr && t != t_invalid) {
|
||||
@@ -1844,8 +2052,9 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity
|
||||
case_ast_node(instr, AsmInstruction, instruction_);
|
||||
GB_ASSERT(instr->name->kind == Ast_Ident);
|
||||
|
||||
u16 mnemonic = 0;
|
||||
CheckMnemomicResult res = check_mnemonic_name(asm_ctx, instr, &mnemonic);
|
||||
u16 mnemonic = 0;
|
||||
u8 suffix_flags = 0;
|
||||
CheckMnemomicResult res = check_mnemonic_name(asm_ctx, instr, &mnemonic, &suffix_flags);
|
||||
|
||||
array_clear(&operands);
|
||||
for (Ast *expr : instr->operands) {
|
||||
@@ -1864,12 +2073,35 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity
|
||||
previous_prefix = cast(u8)mnemonic;
|
||||
previous_prefix_instr = instruction_;
|
||||
} else if (res == CheckMnemomic_Mnemonic) {
|
||||
check_mnemonic(asm_ctx, ctx, entity, instr, mnemonic, slice_from_array(operands),
|
||||
instr->suffix_flags = suffix_flags;
|
||||
check_mnemonic(asm_ctx, ctx, entity, instr, mnemonic, 0, slice_from_array(operands),
|
||||
previous_prefix, previous_prefix_instr,
|
||||
&asm_acc);
|
||||
|
||||
asm_acc.saw_any_instructions = true;
|
||||
|
||||
previous_prefix = 0;
|
||||
previous_prefix_instr = nullptr;
|
||||
} else if (res == CheckMnemomic_PseudoMnemonic) {
|
||||
instr->suffix_flags = suffix_flags;
|
||||
|
||||
u16 pseudo_mnemonic = cast(u16)mnemonic;
|
||||
auto alias = asm_ctx->pseudo_alias(cast(u16)pseudo_mnemonic);
|
||||
u16 target_mnemonic = cast(u16)alias.target;
|
||||
check_mnemonic(asm_ctx, ctx, entity, instr, target_mnemonic, pseudo_mnemonic, slice_from_array(operands),
|
||||
previous_prefix, previous_prefix_instr,
|
||||
&asm_acc);
|
||||
|
||||
asm_acc.saw_any_instructions = true;
|
||||
|
||||
previous_prefix = 0;
|
||||
previous_prefix_instr = nullptr;
|
||||
} else if (res == CheckMnemomic_PseudoMacroMnemonic) {
|
||||
instr->suffix_flags = suffix_flags;
|
||||
check_pseudo_macro_mnemonic(asm_ctx, entity, instr, slice_from_array(operands));
|
||||
|
||||
asm_acc.saw_any_instructions = true;
|
||||
|
||||
previous_prefix = 0;
|
||||
previous_prefix_instr = nullptr;
|
||||
} else {
|
||||
@@ -2126,6 +2358,8 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity
|
||||
gb_internal void check_asm_template_from_entity(CheckerContext *c, Entity *e, DeclInfo *d) {
|
||||
if (build_context.metrics.arch == TargetArch_amd64) {
|
||||
check_asm_template(&g_asm_amd64, c, e, d);
|
||||
} else if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
check_asm_template(&g_asm_riscv, c, e, d);
|
||||
} else {
|
||||
error(e->token, "asm templates are not currently supported for this target");
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4321,7 +4321,7 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
bool failed_to_cache_parsing = false;
|
||||
|
||||
TIME_SECTION("init asm tables");
|
||||
init_asm_tables();
|
||||
init_asm_tables(build_context.metrics.ptr_size);
|
||||
|
||||
MAIN_TIME_SECTION("parse files");
|
||||
|
||||
|
||||
@@ -2484,6 +2484,16 @@ gb_internal Ast *parse_asm_operand(AstFile *f, bool allow_memory_operand) {
|
||||
case Token_Float:
|
||||
case Token_Rune:
|
||||
return ast_basic_lit(f, advance_token(f));
|
||||
|
||||
case Token_Add:
|
||||
case Token_Sub:
|
||||
case Token_Xor:
|
||||
{
|
||||
Token token = advance_token(f);
|
||||
Ast *op = parse_asm_operand(f, false);
|
||||
return ast_unary_expr(f, token, op);
|
||||
}
|
||||
|
||||
case Token_OpenParen:
|
||||
return parse_expr(f, false);
|
||||
case Token_OpenBracket:
|
||||
@@ -2805,8 +2815,11 @@ gb_internal Ast *parse_asm_template(AstFile *f) {
|
||||
asm_instructions = slice_from_array(instructions);
|
||||
}
|
||||
|
||||
if (build_context.metrics.arch != TargetArch_amd64) {
|
||||
syntax_error(token, "asm templates are currently only supported on -target:amd64");
|
||||
if (build_context.metrics.arch == TargetArch_amd64 ||
|
||||
build_context.metrics.arch == TargetArch_riscv64) {
|
||||
// okay
|
||||
} else {
|
||||
syntax_error(token, "asm templates are currently only supported on -target:*_amd64 or -target:*_riscv64");
|
||||
}
|
||||
|
||||
Ast *asm_template = alloc_ast_node(f, Ast_AsmTemplate);
|
||||
|
||||
@@ -507,6 +507,7 @@ struct AstSplitArgs {
|
||||
Ast * name; \
|
||||
Slice<Ast *> operands; \
|
||||
u16 mnemonic; \
|
||||
u8 suffix_flags; \
|
||||
i32 valid_form_index; \
|
||||
}) \
|
||||
AST_KIND(AsmMemoryOperand, "asm memory operand", struct { \
|
||||
|
||||
Reference in New Issue
Block a user