Table of Contents
1. WRITE A RISCV ASSEMBLER
1.1. INSTRUCTION ENCODER
U-TYPE ( IMM RD OPCDOE -- INST ) J-TYPE ( IMM RD OPCODE -- INST ) I-TYPE ( IMM RS1 RD FUNCT3 OPCODE -- INST ) S-TYPE ( IMM RS2 RS1 FUNCT3 OPCODE -- INST ) B-TYPE ( IMM RS2 RS1 FUNCT3 OPCODE -- INST ) R-TYPE ( FUNCT7 RS2 RS1 FUNCT3 RD OPCODE -- INST )
1.2. INSTRUCTION
: LUI, ( IMM RD -- ) $37 U-TYPE L, ;
1.3. INSTRCUTION DECODER
DIS-U-TYPE ( INST -- IMM RD OPCDOE ) DIS-J-TYPE ( INST -- IMM RD OPCODE ) DIS-I-TYPE ( INST -- IMM RS1 RD FUNCT3 OPCODE ) DIS-S-TYPE ( INST -- IMM RS2 RS1 FUNCT3 OPCODE ) DIS-B-TYPE ( INST -- IMM RS2 RS1 FUNCT3 OPCODE ) DIS-R-TYPE ( INST -- FUNCT7 RS2 RS1 FUNCT3 RD OPCODE )
1.4. HOW TO TEST
USE INSTRUCTION ENCODER GENERATE DATA, THEN USE GNU GAS GENERATE TEST RESULT, COMPARE OUTPUT
USE INSTRUCTION ENCODER GENERATE DATA, THEN USE INSTRUCTION DECODER DEOCDE IT, COMPARE INPUT
1.5. GAS
I USE GAS TO GENERATE TEST PATTERN, BUT GAS HAVE SOME OPTIMIZE FOR BRANCH INSTRUCTION:
beq x0, x0, 0
WILL GENERATE:
f4: 00001463 bnez zero,fc <.text+0xfc> f8: 0000006f j f8 <.text+0xf8>
SO I SWITCH TO 'llvm-mc' GENERATE SINGLE BRANCH INSTRUCTION
1.6. LLVM-MC
COMMAND:
llvm-mc -triple=riscv32 -filetype=obj test.S -o a.out
GENERATE COMPRESSED INSTRUCTION, ADD INTO ASM FILE:
.option arch,rv32ic
1.7. FAR CALL
1.8. J TYPE ENCODING
11111111111111110000000000000000 FEDCBA9876543210FEDCBA9876543210 10000000000011110000000000000000 4A987654321B3210FEDC432106543210 O R O F D P F C S O E D T E
1.9. CJ TYPE ENCODING
FEDCBA9876543210 210B498A67321510 F O O U F P N F C C S O T E D 3 T E
1.10. CB TYPE ENCODING
FEDCBA9876543210 2108432107621510 F O R O O U F S F P N F 1 F C C S S O T E E D 3 T T E