SB $0, X5, X6 // 23005300
SB $4, X5, X6 // 23025300
- // 5.2: Integer Computational Instructions (RV64I)
+ // 5.2: Integer Computational Instructions (RV64I)
ADDIW $1, X5, X6 // 1b831200
SLLIW $1, X5, X6 // 1b931200
SRLIW $1, X5, X6 // 1bd31200
RDTIME X5 // f32210c0
RDINSTRET X5 // f32220c0
+ // 11.5: Single-Precision Load and Store Instructions
+ FLW $0, X5, F0 // 07a00200
+ FLW $4, X5, F0 // 07a04200
+ FSW $0, F0, X5 // 27a00200
+ FSW $4, F0, X5 // 27a20200
+
+ // 11.6: Single-Precision Floating-Point Computational Instructions
+ FADDS F1, F0, F2 // 53011000
+ FSUBS F1, F0, F2 // 53011008
+ FMULS F1, F0, F2 // 53011010
+ FDIVS F1, F0, F2 // 53011018
+ FMINS F1, F0, F2 // 53011028
+ FMAXS F1, F0, F2 // 53111028
+ FSQRTS F0, F1 // d3000058
+
+ // 11.7: Single-Precision Floating-Point Conversion and Move Instructions
+ FCVTWS F0, X5 // d31200c0
+ FCVTLS F0, X5 // d31220c0
+ FCVTSW X5, F0 // 538002d0
+ FCVTSL X5, F0 // 538022d0
+ FCVTWUS F0, X5 // d31210c0
+ FCVTLUS F0, X5 // d31230c0
+ FCVTSWU X5, F0 // 538012d0
+ FCVTSLU X5, F0 // 538032d0
+ FSGNJS F1, F0, F2 // 53011020
+ FSGNJNS F1, F0, F2 // 53111020
+ FSGNJXS F1, F0, F2 // 53211020
+ FMVXS F0, X5 // d30200e0
+ FMVSX X5, F0 // 538002f0
+ FMVXW F0, X5 // d30200e0
+ FMVWX X5, F0 // 538002f0
+
+ // 11.8: Single-Precision Floating-Point Compare Instructions
+ FEQS F0, F1, X7 // d3a300a0
+ FLTS F0, F1, X7 // d39300a0
+ FLES F0, F1, X7 // d38300a0
+
+ // 12.3: Double-Precision Load and Store Instructions
+ FLD $0, X5, F0 // 07b00200
+ FLD $4, X5, F0 // 07b04200
+ FSD $0, F0, X5 // 27b00200
+ FSD $4, F0, X5 // 27b20200
+
+ // 12.4: Double-Precision Floating-Point Computational Instructions
+ FADDD F1, F0, F2 // 53011002
+ FSUBD F1, F0, F2 // 5301100a
+ FMULD F1, F0, F2 // 53011012
+ FDIVD F1, F0, F2 // 5301101a
+ FMIND F1, F0, F2 // 5301102a
+ FMAXD F1, F0, F2 // 5311102a
+ FSQRTD F0, F1 // d300005a
+
+ // 12.5: Double-Precision Floating-Point Conversion and Move Instructions
+ FCVTWD F0, X5 // d31200c2
+ FCVTLD F0, X5 // d31220c2
+ FCVTDW X5, F0 // 538002d2
+ FCVTDL X5, F0 // 538022d2
+ FCVTWUD F0, X5 // d31210c2
+ FCVTLUD F0, X5 // d31230c2
+ FCVTDWU X5, F0 // 538012d2
+ FCVTDLU X5, F0 // 538032d2
+ FCVTSD F0, F1 // d3001040
+ FCVTDS F0, F1 // d3000042
+ FSGNJD F1, F0, F2 // 53011022
+ FSGNJND F1, F0, F2 // 53111022
+ FSGNJXD F1, F0, F2 // 53211022
+ FMVXD F0, X5 // d30200e2
+ FMVDX X5, F0 // 538002f2
+
// Privileged ISA
// 3.2.1: Environment Call and Breakpoint
if p.To.Type == obj.TYPE_NONE {
p.To.Type, p.To.Reg = obj.TYPE_REG, REG_ZERO
}
+
+ case AFSQRTS, AFSQRTD:
+ // These instructions expect a zero (i.e. float register 0)
+ // to be the second input operand.
+ p.Reg = p.From.Reg
+ p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_F0}
+
+ case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD:
+ // Set the rounding mode in funct3 to round to zero.
+ p.Scond = 1
}
}
return regVal(r, REG_X0, REG_X31)
}
+// regF returns a float register.
+func regF(r int16) uint32 {
+ return regVal(r, REG_F0, REG_F31)
+}
+
// regAddr extracts a register from an Addr.
func regAddr(a obj.Addr, min, max int16) uint32 {
if a.Type != obj.TYPE_REG {
return regAddr(a, REG_X0, REG_X31)
}
+// regFAddr extracts the float register from an Addr.
+func regFAddr(a obj.Addr) uint32 {
+ return regAddr(a, REG_F0, REG_F31)
+}
+
// immFits reports whether immediate value x fits in nbits bits as a
// signed integer.
func immFits(x int64, nbits uint) bool {
wantReg(p, pos, "integer", r, REG_X0, REG_X31)
}
+// wantFloatReg checks that r is a floating-point register.
+func wantFloatReg(p *obj.Prog, pos string, r int16) {
+ wantReg(p, pos, "float", r, REG_F0, REG_F31)
+}
+
func wantRegAddr(p *obj.Prog, pos string, a *obj.Addr, descr string, min int16, max int16) {
if a == nil {
p.Ctxt.Diag("%v\texpected register in %s position but got nothing", p, pos)
wantRegAddr(p, pos, a, "integer", REG_X0, REG_X31)
}
+// wantFloatRegAddr checks that a contains a floating-point register.
+func wantFloatRegAddr(p *obj.Prog, pos string, a *obj.Addr) {
+ wantRegAddr(p, pos, a, "float", REG_F0, REG_F31)
+}
+
func validateRIII(p *obj.Prog) {
wantIntRegAddr(p, "from", &p.From)
wantIntReg(p, "reg", p.Reg)
wantIntRegAddr(p, "to", &p.To)
}
+func validateRFFF(p *obj.Prog) {
+ wantFloatRegAddr(p, "from", &p.From)
+ wantFloatReg(p, "reg", p.Reg)
+ wantFloatRegAddr(p, "to", &p.To)
+}
+
+func validateRFFI(p *obj.Prog) {
+ wantFloatRegAddr(p, "from", &p.From)
+ wantFloatReg(p, "reg", p.Reg)
+ wantIntRegAddr(p, "to", &p.To)
+}
+
+func validateRFI(p *obj.Prog) {
+ wantFloatRegAddr(p, "from", &p.From)
+ wantIntRegAddr(p, "to", &p.To)
+}
+
+func validateRIF(p *obj.Prog) {
+ wantIntRegAddr(p, "from", &p.From)
+ wantFloatRegAddr(p, "to", &p.To)
+}
+
+func validateRFF(p *obj.Prog) {
+ wantFloatRegAddr(p, "from", &p.From)
+ wantFloatRegAddr(p, "to", &p.To)
+}
+
func validateII(p *obj.Prog) {
wantImm(p, "from", p.From, 12)
wantIntReg(p, "reg", p.Reg)
wantIntRegAddr(p, "to", &p.To)
}
+func validateIF(p *obj.Prog) {
+ wantImm(p, "from", p.From, 12)
+ wantIntReg(p, "reg", p.Reg)
+ wantFloatRegAddr(p, "to", &p.To)
+}
+
func validateSI(p *obj.Prog) {
wantImm(p, "from", p.From, 12)
wantIntReg(p, "reg", p.Reg)
wantIntRegAddr(p, "to", &p.To)
}
+func validateSF(p *obj.Prog) {
+ wantImm(p, "from", p.From, 12)
+ wantFloatReg(p, "reg", p.Reg)
+ wantIntRegAddr(p, "to", &p.To)
+}
+
func validateRaw(p *obj.Prog) {
// Treat the raw value specially as a 32-bit unsigned integer.
// Nobody wants to enter negative machine code.
return encodeR(p, regI(p.Reg), regIAddr(p.From), regIAddr(p.To))
}
+func encodeRFFF(p *obj.Prog) uint32 {
+ return encodeR(p, regF(p.Reg), regFAddr(p.From), regFAddr(p.To))
+}
+
+func encodeRFFI(p *obj.Prog) uint32 {
+ return encodeR(p, regF(p.Reg), regFAddr(p.From), regIAddr(p.To))
+}
+
+func encodeRFI(p *obj.Prog) uint32 {
+ return encodeR(p, regFAddr(p.From), 0, regIAddr(p.To))
+}
+
+func encodeRIF(p *obj.Prog) uint32 {
+ return encodeR(p, regIAddr(p.From), 0, regFAddr(p.To))
+}
+
+func encodeRFF(p *obj.Prog) uint32 {
+ return encodeR(p, regFAddr(p.From), 0, regFAddr(p.To))
+}
+
// encodeI encodes an I-type RISC-V instruction.
func encodeI(p *obj.Prog, rd uint32) uint32 {
imm := immI(p.From, 12)
return encodeI(p, regIAddr(p.To))
}
+func encodeIF(p *obj.Prog) uint32 {
+ return encodeI(p, regFAddr(p.To))
+}
+
// encodeS encodes an S-type RISC-V instruction.
func encodeS(p *obj.Prog, rs2 uint32) uint32 {
imm := immI(p.From, 12)
return encodeS(p, regI(p.Reg))
}
+func encodeSF(p *obj.Prog) uint32 {
+ return encodeS(p, regF(p.Reg))
+}
+
// encodeRaw encodes a raw instruction value.
func encodeRaw(p *obj.Prog) uint32 {
// Treat the raw value specially as a 32-bit unsigned integer.
// indicates an S-type instruction with rs2 being a float register.
rIIIEncoding = encoding{encode: encodeRIII, validate: validateRIII, length: 4}
+ rFFFEncoding = encoding{encode: encodeRFFF, validate: validateRFFF, length: 4}
+ rFFIEncoding = encoding{encode: encodeRFFI, validate: validateRFFI, length: 4}
+ rFIEncoding = encoding{encode: encodeRFI, validate: validateRFI, length: 4}
+ rIFEncoding = encoding{encode: encodeRIF, validate: validateRIF, length: 4}
+ rFFEncoding = encoding{encode: encodeRFF, validate: validateRFF, length: 4}
iIEncoding = encoding{encode: encodeII, validate: validateII, length: 4}
+ iFEncoding = encoding{encode: encodeIF, validate: validateIF, length: 4}
sIEncoding = encoding{encode: encodeSI, validate: validateSI, length: 4}
+ sFEncoding = encoding{encode: encodeSF, validate: validateSF, length: 4}
// rawEncoding encodes a raw instruction byte sequence.
rawEncoding = encoding{encode: encodeRaw, validate: validateRaw, length: 4}
ARDTIME & obj.AMask: iIEncoding,
ARDINSTRET & obj.AMask: iIEncoding,
+ // 11.5: Single-Precision Load and Store Instructions
+ AFLW & obj.AMask: iFEncoding,
+ AFSW & obj.AMask: sFEncoding,
+
+ // 11.6: Single-Precision Floating-Point Computational Instructions
+ AFADDS & obj.AMask: rFFFEncoding,
+ AFSUBS & obj.AMask: rFFFEncoding,
+ AFMULS & obj.AMask: rFFFEncoding,
+ AFDIVS & obj.AMask: rFFFEncoding,
+ AFMINS & obj.AMask: rFFFEncoding,
+ AFMAXS & obj.AMask: rFFFEncoding,
+ AFSQRTS & obj.AMask: rFFFEncoding,
+
+ // 11.7: Single-Precision Floating-Point Conversion and Move Instructions
+ AFCVTWS & obj.AMask: rFIEncoding,
+ AFCVTLS & obj.AMask: rFIEncoding,
+ AFCVTSW & obj.AMask: rIFEncoding,
+ AFCVTSL & obj.AMask: rIFEncoding,
+ AFCVTWUS & obj.AMask: rFIEncoding,
+ AFCVTLUS & obj.AMask: rFIEncoding,
+ AFCVTSWU & obj.AMask: rIFEncoding,
+ AFCVTSLU & obj.AMask: rIFEncoding,
+ AFSGNJS & obj.AMask: rFFFEncoding,
+ AFSGNJNS & obj.AMask: rFFFEncoding,
+ AFSGNJXS & obj.AMask: rFFFEncoding,
+ AFMVXS & obj.AMask: rFIEncoding,
+ AFMVSX & obj.AMask: rIFEncoding,
+ AFMVXW & obj.AMask: rFIEncoding,
+ AFMVWX & obj.AMask: rIFEncoding,
+
+ // 11.8: Single-Precision Floating-Point Compare Instructions
+ AFEQS & obj.AMask: rFFIEncoding,
+ AFLTS & obj.AMask: rFFIEncoding,
+ AFLES & obj.AMask: rFFIEncoding,
+
+ // 12.3: Double-Precision Load and Store Instructions
+ AFLD & obj.AMask: iFEncoding,
+ AFSD & obj.AMask: sFEncoding,
+
+ // 12.4: Double-Precision Floating-Point Computational Instructions
+ AFADDD & obj.AMask: rFFFEncoding,
+ AFSUBD & obj.AMask: rFFFEncoding,
+ AFMULD & obj.AMask: rFFFEncoding,
+ AFDIVD & obj.AMask: rFFFEncoding,
+ AFMIND & obj.AMask: rFFFEncoding,
+ AFMAXD & obj.AMask: rFFFEncoding,
+ AFSQRTD & obj.AMask: rFFFEncoding,
+
+ // 12.5: Double-Precision Floating-Point Conversion and Move Instructions
+ AFCVTWD & obj.AMask: rFIEncoding,
+ AFCVTLD & obj.AMask: rFIEncoding,
+ AFCVTDW & obj.AMask: rIFEncoding,
+ AFCVTDL & obj.AMask: rIFEncoding,
+ AFCVTWUD & obj.AMask: rFIEncoding,
+ AFCVTLUD & obj.AMask: rFIEncoding,
+ AFCVTDWU & obj.AMask: rIFEncoding,
+ AFCVTDLU & obj.AMask: rIFEncoding,
+ AFCVTSD & obj.AMask: rFFEncoding,
+ AFCVTDS & obj.AMask: rFFEncoding,
+ AFSGNJD & obj.AMask: rFFFEncoding,
+ AFSGNJND & obj.AMask: rFFFEncoding,
+ AFSGNJXD & obj.AMask: rFFFEncoding,
+ AFMVXD & obj.AMask: rFIEncoding,
+ AFMVDX & obj.AMask: rIFEncoding,
+
+ // 12.6: Double-Precision Floating-Point Compare Instructions
+ AFEQD & obj.AMask: rFFIEncoding,
+ AFLTD & obj.AMask: rFFIEncoding,
+ AFLED & obj.AMask: rFFIEncoding,
+
// Privileged ISA
// 3.2.1: Environment Call and Breakpoint