TEXT asmtest(SB),DUPOK|NOSPLIT,$0
- // Arbitrary bytes (entered in little-endian mode)
- WORD $0x12345678 // WORD $305419896 // 78563412
- WORD $0x9abcdef0 // WORD $2596069104 // f0debc9a
-
// Unprivileged ISA
// 2.4: Integer Computational Instructions
SRA X5, X6 // 33535340
SRA $1, X5, X6 // 13d31240
SRA $1, X5 // 93d21240
+
+ // 2.6: Load and Store Instructions
+ LW $0, X5, X6 // 03a30200
+ LW $4, X5, X6 // 03a34200
+ LWU $0, X5, X6 // 03e30200
+ LWU $4, X5, X6 // 03e34200
+ LH $0, X5, X6 // 03930200
+ LH $4, X5, X6 // 03934200
+ LHU $0, X5, X6 // 03d30200
+ LHU $4, X5, X6 // 03d34200
+ LB $0, X5, X6 // 03830200
+ LB $4, X5, X6 // 03834200
+ LBU $0, X5, X6 // 03c30200
+ LBU $4, X5, X6 // 03c34200
+
+ SW $0, X5, X6 // 23205300
+ SW $4, X5, X6 // 23225300
+ SH $0, X5, X6 // 23105300
+ SH $4, X5, X6 // 23125300
+ SB $0, X5, X6 // 23005300
+ SB $4, X5, X6 // 23025300
+
+ // 5.3: Load and Store Instructions (RV64I)
+ LD $0, X5, X6 // 03b30200
+ LD $4, X5, X6 // 03b34200
+ SD $0, X5, X6 // 23305300
+ SD $4, X5, X6 // 23325300
+
+ // 7.1: Multiplication Operations
+ MUL X5, X6, X7 // b3035302
+ MULH X5, X6, X7 // b3135302
+ MULHU X5, X6, X7 // b3335302
+ MULHSU X5, X6, X7 // b3235302
+ MULW X5, X6, X7 // bb035302
+ DIV X5, X6, X7 // b3435302
+ DIVU X5, X6, X7 // b3535302
+ REM X5, X6, X7 // b3635302
+ REMU X5, X6, X7 // b3735302
+ DIVW X5, X6, X7 // bb435302
+ DIVUW X5, X6, X7 // bb535302
+ REMW X5, X6, X7 // bb635302
+ REMUW X5, X6, X7 // bb735302
+
+ // Arbitrary bytes (entered in little-endian mode)
+ WORD $0x12345678 // WORD $305419896 // 78563412
+ WORD $0x9abcdef0 // WORD $2596069104 // f0debc9a
wantIntRegAddr(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 validateRaw(p *obj.Prog) {
// Treat the raw value specially as a 32-bit unsigned integer.
// Nobody wants to enter negative machine code.
return encodeI(p, regIAddr(p.To))
}
+// encodeS encodes an S-type RISC-V instruction.
+func encodeS(p *obj.Prog, rs2 uint32) uint32 {
+ imm := immI(p.From, 12)
+ rs1 := regIAddr(p.To)
+ i := encode(p.As)
+ if i == nil {
+ panic("encodeS: could not encode instruction")
+ }
+ return (imm>>5)<<25 | rs2<<20 | rs1<<15 | i.funct3<<12 | (imm&0x1f)<<7 | i.opcode
+}
+
+func encodeSI(p *obj.Prog) uint32 {
+ return encodeS(p, regI(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.
iIEncoding = encoding{encode: encodeII, validate: validateII, length: 4}
+ sIEncoding = encoding{encode: encodeSI, validate: validateSI, length: 4}
+
// rawEncoding encodes a raw instruction byte sequence.
rawEncoding = encoding{encode: encodeRaw, validate: validateRaw, length: 4}
ASUB & obj.AMask: rIIIEncoding,
ASRA & obj.AMask: rIIIEncoding,
+ // 2.6: Load and Store Instructions
+ ALW & obj.AMask: iIEncoding,
+ ALWU & obj.AMask: iIEncoding,
+ ALH & obj.AMask: iIEncoding,
+ ALHU & obj.AMask: iIEncoding,
+ ALB & obj.AMask: iIEncoding,
+ ALBU & obj.AMask: iIEncoding,
+ ASW & obj.AMask: sIEncoding,
+ ASH & obj.AMask: sIEncoding,
+ ASB & obj.AMask: sIEncoding,
+
+ // 5.3: Load and Store Instructions (RV64I)
+ ALD & obj.AMask: iIEncoding,
+ ASD & obj.AMask: sIEncoding,
+
+ // 7.1: Multiplication Operations
+ AMUL & obj.AMask: rIIIEncoding,
+ AMULH & obj.AMask: rIIIEncoding,
+ AMULHU & obj.AMask: rIIIEncoding,
+ AMULHSU & obj.AMask: rIIIEncoding,
+ AMULW & obj.AMask: rIIIEncoding,
+ ADIV & obj.AMask: rIIIEncoding,
+ ADIVU & obj.AMask: rIIIEncoding,
+ AREM & obj.AMask: rIIIEncoding,
+ AREMU & obj.AMask: rIIIEncoding,
+ ADIVW & obj.AMask: rIIIEncoding,
+ ADIVUW & obj.AMask: rIIIEncoding,
+ AREMW & obj.AMask: rIIIEncoding,
+ AREMUW & obj.AMask: rIIIEncoding,
+
// Escape hatch
AWORD & obj.AMask: rawEncoding,