diff --git a/riscv64/riscv64asm/arg.go b/riscv64/riscv64asm/arg.go index 2b96b416..9adac5a6 100644 --- a/riscv64/riscv64asm/arg.go +++ b/riscv64/riscv64asm/arg.go @@ -140,4 +140,7 @@ const ( arg_c_nzuimm10 arg_c_imm12 arg_c_nzimm18 + + arg_c_uimm1 + arg_c_uimm2 ) diff --git a/riscv64/riscv64asm/decode.go b/riscv64/riscv64asm/decode.go index 390edfa9..b0feb70a 100644 --- a/riscv64/riscv64asm/decode.go +++ b/riscv64/riscv64asm/decode.go @@ -372,6 +372,14 @@ func decodeArg(aop argType, x uint32, index int) Arg { } return Simm{int32(imm), true, 18} + case arg_c_uimm2: + imm := ((x>>6)&1) | (((x>>5)&1) << 1) + return Uimm{imm, false} + + case arg_c_uimm1: + imm := ((x >> 5) & 0x1) << 1 + return Uimm{imm, false} + default: return nil } @@ -591,6 +599,70 @@ func convertCompressedIns(f *instFormat, args Args) Args { newargs[0] = Reg(X0) newargs[1] = CSR(CYCLE) newargs[2] = Reg(X0) + + case C_LBU: + f.op = LBU + newargs[0] = args[0] + newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}} + + case C_LHU: + f.op = LHU + newargs[0] = args[0] + newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}} + + case C_LH: + f.op = LH + newargs[0] = args[0] + newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}} + + case C_SB: + f.op = SB + newargs[0] = args[0] + newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}} + + case C_SH: + f.op = SH + newargs[0] = args[0] + newargs[1] = RegOffset{args[1].(Reg), Simm{int32(args[2].(Uimm).Imm), true, 12}} + + case C_MUL: + f.op = MUL + newargs[0] = args[0] + newargs[1] = args[0] + newargs[2] = args[1] + + case C_NOT: + f.op = XORI + newargs[0] = args[0] + newargs[1] = args[0] + newargs[2] = Simm{-1, true, 12} + + case C_SEXT_B: + f.op = SEXT_B + newargs[0] = args[0] + newargs[1] = args[0] + + case C_SEXT_H: + f.op = SEXT_H + newargs[0] = args[0] + newargs[1] = args[0] + + case C_ZEXT_B: + f.op = ANDI + newargs[0] = args[0] + newargs[1] = args[0] + newargs[2] = Simm{255, true, 12} + + case C_ZEXT_H: + f.op = ZEXT_H + newargs[0] = args[0] + newargs[1] = args[0] + + case C_ZEXT_W: + f.op = ADD_UW + newargs[0] = args[0] + newargs[1] = args[0] + newargs[2] = Reg(X0) } return newargs } diff --git a/riscv64/riscv64asm/objdumpext_test.go b/riscv64/riscv64asm/objdumpext_test.go index acbd9256..32aec500 100644 --- a/riscv64/riscv64asm/objdumpext_test.go +++ b/riscv64/riscv64asm/objdumpext_test.go @@ -290,7 +290,7 @@ func writeELF64(f *os.File, size int) error { // RISC-V objdump needs the .riscv.attributes section to identify extensions. exts := "rv64i2p0_m2p0_a2p0_f2p0_d2p0_q2p0_c2p0_v1p0_" + "zicbom1p0_zicbop1p0_zicboz1p0_zicond1p0_zmmul1p0_" + - "zfh1p0_zfhmin1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0_" + + "zfh1p0_zfhmin1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0_zcb1p0_" + "zvkg1p0_zvkned1p0_zvknha1p0_zvknhb1p0_zvksed1p0_zvksh1p0" b := buildRISCVAttributes(exts) sect = elf.Section64{ diff --git a/riscv64/riscv64asm/plan9x.go b/riscv64/riscv64asm/plan9x.go index 94576245..63aa2532 100644 --- a/riscv64/riscv64asm/plan9x.go +++ b/riscv64/riscv64asm/plan9x.go @@ -71,7 +71,7 @@ goSyntaxSwitch: case ADDIW: if inst.Args[2].(Simm).Imm == 0 { - op = "MOVW" + op = "SEXTW" args = args[:len(args)-1] } @@ -390,6 +390,7 @@ goSyntaxSwitch: case VSETVL: args[0], args[2] = args[2], args[0] + } // Reverse args, placing dest last. diff --git a/riscv64/riscv64asm/tables.go b/riscv64/riscv64asm/tables.go index 1de060f1..41805f50 100644 --- a/riscv64/riscv64asm/tables.go +++ b/riscv64/riscv64asm/tables.go @@ -142,17 +142,26 @@ const ( C_J C_JALR C_JR + C_LBU C_LD C_LDSP + C_LH + C_LHU C_LI C_LUI C_LW C_LWSP + C_MUL C_MV C_NOP + C_NOT C_OR + C_SB C_SD C_SDSP + C_SEXT_B + C_SEXT_H + C_SH C_SLLI C_SRAI C_SRLI @@ -162,6 +171,9 @@ const ( C_SWSP C_UNIMP C_XOR + C_ZEXT_B + C_ZEXT_H + C_ZEXT_W DIV DIVU DIVUW @@ -1166,17 +1178,26 @@ var opstr = [...]string{ C_J: "C.J", C_JALR: "C.JALR", C_JR: "C.JR", + C_LBU: "C.LBU", C_LD: "C.LD", C_LDSP: "C.LDSP", + C_LH: "C.LH", + C_LHU: "C.LHU", C_LI: "C.LI", C_LUI: "C.LUI", C_LW: "C.LW", C_LWSP: "C.LWSP", + C_MUL: "C.MUL", C_MV: "C.MV", C_NOP: "C.NOP", + C_NOT: "C.NOT", C_OR: "C.OR", + C_SB: "C.SB", C_SD: "C.SD", C_SDSP: "C.SDSP", + C_SEXT_B: "C.SEXT.B", + C_SEXT_H: "C.SEXT.H", + C_SH: "C.SH", C_SLLI: "C.SLLI", C_SRAI: "C.SRAI", C_SRLI: "C.SRLI", @@ -1186,6 +1207,9 @@ var opstr = [...]string{ C_SWSP: "C.SWSP", C_UNIMP: "C.UNIMP", C_XOR: "C.XOR", + C_ZEXT_B: "C.ZEXT.B", + C_ZEXT_H: "C.ZEXT.H", + C_ZEXT_W: "C.ZEXT.W", DIV: "DIV", DIVU: "DIVU", DIVUW: "DIVUW", @@ -2324,10 +2348,16 @@ var instFormats = [...]instFormat{ {mask: 0x0000f07f, value: 0x00009002, op: C_JALR, args: argTypeList{arg_c_rs1_n0}}, // C.JR rs1_n0 {mask: 0x0000f07f, value: 0x00008002, op: C_JR, args: argTypeList{arg_rs1_n0}}, + // C.LBU rd_p, rs1_p, c_uimm2 + {mask: 0x0000fc03, value: 0x00008000, op: C_LBU, args: argTypeList{arg_rd_p, arg_rs1_p, arg_c_uimm2}}, // C.LD rd_p, rs1_p, c_uimm8 {mask: 0x0000e003, value: 0x00006000, op: C_LD, args: argTypeList{arg_rd_p, arg_rs1_p, arg_c_uimm8}}, // C.LDSP rd_n0, c_uimm9sp {mask: 0x0000e003, value: 0x00006002, op: C_LDSP, args: argTypeList{arg_rd_n0, arg_c_uimm9sp}}, + // C.LH rd_p, rs1_p, c_uimm1 + {mask: 0x0000fc43, value: 0x00008440, op: C_LH, args: argTypeList{arg_rd_p, arg_rs1_p, arg_c_uimm1}}, + // C.LHU rd_p, rs1_p, c_uimm1 + {mask: 0x0000fc43, value: 0x00008400, op: C_LHU, args: argTypeList{arg_rd_p, arg_rs1_p, arg_c_uimm1}}, // C.LI rd_n0, c_imm6 {mask: 0x0000e003, value: 0x00004001, op: C_LI, args: argTypeList{arg_rd_n0, arg_c_imm6}}, // C.LUI rd_n2, c_nzimm18 @@ -2336,16 +2366,28 @@ var instFormats = [...]instFormat{ {mask: 0x0000e003, value: 0x00004000, op: C_LW, args: argTypeList{arg_rd_p, arg_rs1_p, arg_c_uimm7}}, // C.LWSP rd_n0, c_uimm8sp {mask: 0x0000e003, value: 0x00004002, op: C_LWSP, args: argTypeList{arg_rd_n0, arg_c_uimm8sp}}, + // C.MUL rd_rs1_p, rs2_p + {mask: 0x0000fc63, value: 0x00009c41, op: C_MUL, args: argTypeList{arg_rd_rs1_p, arg_rs2_p}}, // C.MV rd_n0, c_rs2_n0 {mask: 0x0000f003, value: 0x00008002, op: C_MV, args: argTypeList{arg_rd_n0, arg_c_rs2_n0}}, // C.NOP c_nzimm6 {mask: 0x0000ef83, value: 0x00000001, op: C_NOP, args: argTypeList{arg_c_nzimm6}}, + // C.NOT rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c75, op: C_NOT, args: argTypeList{arg_rd_rs1_p}}, // C.OR rd_rs1_p, rs2_p {mask: 0x0000fc63, value: 0x00008c41, op: C_OR, args: argTypeList{arg_rd_rs1_p, arg_rs2_p}}, + // C.SB rs2_p, rs1_p, c_uimm2 + {mask: 0x0000fc03, value: 0x00008800, op: C_SB, args: argTypeList{arg_rs2_p, arg_rs1_p, arg_c_uimm2}}, // C.SD rs1_p, rs2_p, c_uimm8 {mask: 0x0000e003, value: 0x0000e000, op: C_SD, args: argTypeList{arg_rs1_p, arg_rs2_p, arg_c_uimm8}}, // C.SDSP c_rs2, c_uimm9sp_s {mask: 0x0000e003, value: 0x0000e002, op: C_SDSP, args: argTypeList{arg_c_rs2, arg_c_uimm9sp_s}}, + // C.SEXT.B rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c65, op: C_SEXT_B, args: argTypeList{arg_rd_rs1_p}}, + // C.SEXT.H rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c6d, op: C_SEXT_H, args: argTypeList{arg_rd_rs1_p}}, + // C.SH rs2_p, rs1_p, c_uimm1 + {mask: 0x0000fc43, value: 0x00008c00, op: C_SH, args: argTypeList{arg_rs2_p, arg_rs1_p, arg_c_uimm1}}, // C.SLLI rd_rs1_n0, c_nzuimm6 {mask: 0x0000e003, value: 0x00000002, op: C_SLLI, args: argTypeList{arg_rd_rs1_n0, arg_c_nzuimm6}}, // C.SRAI rd_rs1_p, c_nzuimm6 @@ -2364,6 +2406,12 @@ var instFormats = [...]instFormat{ {mask: 0x0000ffff, value: 0x00000000, op: C_UNIMP, args: argTypeList{}}, // C.XOR rd_rs1_p, rs2_p {mask: 0x0000fc63, value: 0x00008c21, op: C_XOR, args: argTypeList{arg_rd_rs1_p, arg_rs2_p}}, + // C.ZEXT.B rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c61, op: C_ZEXT_B, args: argTypeList{arg_rd_rs1_p}}, + // C.ZEXT.H rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c69, op: C_ZEXT_H, args: argTypeList{arg_rd_rs1_p}}, + // C.ZEXT.W rd_rs1_p + {mask: 0x0000fc7f, value: 0x00009c71, op: C_ZEXT_W, args: argTypeList{arg_rd_rs1_p}}, // DIV rd, rs1, rs2 {mask: 0xfe00707f, value: 0x02004033, op: DIV, args: argTypeList{arg_rd, arg_rs1, arg_rs2}}, // DIVU rd, rs1, rs2 diff --git a/riscv64/riscv64asm/testdata/gnucases.txt b/riscv64/riscv64asm/testdata/gnucases.txt index 451ed6ae..d1cca895 100644 --- a/riscv64/riscv64asm/testdata/gnucases.txt +++ b/riscv64/riscv64asm/testdata/gnucases.txt @@ -425,6 +425,23 @@ b373530e| czero.nez x7,x6,x5 13e0321c| prefetch.w 448(x5) 13e07200| ori x0,x5,7 +# "Zc*" Extension for Code Size Reduction, Version 1.0.0 + +# 27.8: "zcb" Extension +6c81| lbu x11,3(x10) +2c85| lhu x11,2(x10) +6c85| lh x11,2(x10) +2c89| sb x11,2(x10) +2c8d| sh x11,2(x10) +619d| zext.b x10,x10 +659d| sext.b x10,x10 +699d| zext.h x10,x10 +6d9d| sext.h x10,x10 +759d| not x10,x10 +4d9d| mul x10,x10,x11 +719d| zext.w x10,x10 +0125| sext.w x10,x10 + # "B" Extension for Bit Manipulation, Version 1.0.0 # 28.4.1. Zba: Address generation diff --git a/riscv64/riscv64asm/testdata/plan9cases.txt b/riscv64/riscv64asm/testdata/plan9cases.txt index 451372ca..4689b268 100644 --- a/riscv64/riscv64asm/testdata/plan9cases.txt +++ b/riscv64/riscv64asm/testdata/plan9cases.txt @@ -4,8 +4,8 @@ b3027300| ADD X7, X6, X5 93870900| MOV X19, X15 93070100| MOV X2, X15 9b02f37f| ADDIW $2047, X6, X5 -1b830a00| MOVW X21, X6 -1b810a00| MOVW X21, X2 +1b830a00| SEXTW X21, X6 +1b810a00| SEXTW X21, X2 bb027300| ADDW X7, X6, X5 afb26300| AMOADDD X6, (X7), X5 afb26304| AMOADDD X6, (X7), X5 @@ -378,6 +378,23 @@ b373530e| CZERONEZ X5, X6, X7 13e0321c| PREFETCHW 448(X5) 13e07200| ORI $7, X5, X0 +# "Zc*" Extension for Code Size Reduction, Version 1.0.0 + +# 27.8: "zcb" Extension +6c81| MOVBU 3(X10), X11 +2c85| MOVHU 2(X10), X11 +6c85| MOVH 2(X10), X11 +2c89| MOVB X11, 2(X10) +2c8d| MOVH X11, 2(X10) +619d| MOVBU X10, X10 +659d| SEXTB X10, X10 +699d| ZEXTH X10, X10 +6d9d| SEXTH X10, X10 +759d| NOT X10, X10 +4d9d| MUL X11, X10, X10 +719d| ZEXTW X10, X10 +0125| SEXTW X10, X10 + # "B" Extension for Bit Manipulation, Version 1.0.0 # 28.4.1. Zba: Address generation diff --git a/riscv64/riscv64spec/spec.go b/riscv64/riscv64spec/spec.go index 7c01a444..0ec95785 100644 --- a/riscv64/riscv64spec/spec.go +++ b/riscv64/riscv64spec/spec.go @@ -36,6 +36,7 @@ var extensions = []string{ "rv_zbb", "rv_zbc", "rv_zbs", + "rv_zcb", "rv_zicbo", "rv_zfh", "rv_zfhmin", @@ -57,6 +58,7 @@ var extensions = []string{ "rv64_zba", "rv64_zbb", "rv64_zbs", + "rv64_zcb", "rv64_zfh", } @@ -507,6 +509,12 @@ func decodeArgs(arg string, op string) string { case arg == "c_nzimm18lo": return "arg_c_nzimm18" + + case arg == "c_uimm2": + return "arg_c_uimm2" + + case arg == "c_uimm1": + return "arg_c_uimm1" } return "" }