// //VMEX = 32bit RISCV-like (RV32EM) but NOT binary compatible // // 16 32bit registers // human face 8bit opcodes // human face opcodes hex mnemonics // 16bit immediates (20bit for address) // PC 20bit/24bit/32bit // memory mapped IO // SW MMU // // simple encodings // 31 0 // -------+-------+-------+-------+ // rs2|000|rs1|000|-rd|000|ttttcccc // -------+-------+-------+-------+ // -L-immediate-H-|-rd|rs1|ttttcccc // -------+-------+-------+-------+ // -L-immediate-H-|rs1|rs2|ttttcccc // -------+-------+-------+-------+ // -L-immediate-H-|-rd|iii|ttttcccc // -------+-------+-------+-------+ //OP 00-NOP #define OP00_NOP 0x00 //OP R3-TYPE #define OPR31_ADD 0x31 // rd = rs1 + rs2 //+= // -- registers #define OPR32_SUB 0x32 // rd = rs1 - rs2 //-= #define OPR33_XOR 0x33 // rd = rs1 ^ rs2 //^= #define OPR34_AND 0x34 // rd = rs1 & rs2 //&= #define OPR35_OR 0x35 // rd = rs1 | rs2 //|= #define OPR36_SLL 0x36 // rd = rs1 << rs2 //<<= #define OPR37_SRL 0x37 // rd = rs1 >> rs2 //>>= #define OPR38_SRA 0x38 // rd = rs1 a>> rs2 //a>>= #define OPR3A_CLT 0x3A //SLT // rd = rs1 < rs2 #define OPR3B_CLTU 0x3B //SLTU // rd = rs1 u< rs2 //OP R2-TYPE // "M" extension = multiply/divide #define OPR21_MUL 0x21 // rd = rs1 * rs2 //*= // -- "M" multiply / divide #define OPR22_MULH 0x22 // rd = rs1 * rs2 //*= #define OPR23_MULHU 0x23 // rd = rs1 u* rs2 //u*= #define OPR24_MULHSU 0x24 // rd = rs1 u* rs2 //u*= #define OPR25_DIV 0x25 // rd = rs1 / rs2 ///= #define OPR26_DIVU 0x26 // rd = rs1 u/ rs2 //u/= #define OPR27_REM 0x27 // rd = rs1 % rs2 //%= #define OPR28_REMU 0x28 // rd = rs1 u% rs2 //u%= //OP I3-TYPE #define OPI11_ADDI 0x11 // rd = rs1 + imm //+= // -- immediates #define OPI12_SUBI 0x12 //pseudo // rd = rs1 - imm //-= #define OPI13_XORI 0x13 // rd = rs1 ^ imm //^= #define OPI14_ANDI 0x14 // rd = rs1 & imm //&= #define OPI15_ORI 0x15 // rd = rs1 | imm //|= #define OPI16_SLLI 0x16 // rd = rs1 << imm //<<= #define OPI17_SRLI 0x17 // rd = rs1 >> imm //>>= #define OPI18_SRAI 0x18 // rd = rs1 a>> imm //a>>= #define OPI1A_CLTI 0x1A //SLTI // rd = rs1 < imm #define OPI1B_CLTIU 0x1B //SLTIU // rd = rs1 u< rs2 #define OPI1E_LI 0x1E //pseudo //16bit #define OPI1F_LI 0x1F //TODO //pseudo //LUI+ORI combined (fusion)??? //OP IC-TYPE #define OPIC1_CLTZ 0xC1 //pseudo // rd = rs1 < 0 // -- compare to 0 (optimized) //#define OPIC2_CLEZ 0xC2 //pseudo // rd = rs1 <= 0 #define OPIC3_CNEZ 0xC3 //pseudo // rd = rs1 != 0 #define OPIC4_CEQZ 0xC4 //pseudo // rd = rs1 == 0 //#define OPIC5_CGEZ 0xC5 //pseudo // rd = rs1 >= 0 #define OPIC6_CGTZ 0xC6 //pseudo // rd = rs1 > 0 //OP ID-TYPE #define OPIDD_MOV 0xDD //pseudo //MV // -- moves, inits, unary #define OPID0_INI 0xD0 //pseudo //MV (optimized 0) #define OPIDE_NEG 0xDE //pseudo #define OPIDF_NOT 0xDF //pseudo //#define OPRD1_MV1 0cD1 //pseudo //aslix //DB //D1 //move byte //#define OPRD2_MV2 0cD2 //pseudo //aslix //DD //D2 //move dual byte (H) //#define OPRD3_MV3 0cD3 //pseudo //aslix //move third byte ??? aslix?? //#define OPRD4_MV4 0cD4 //pseudo //aslix //move fourth byte ??? aslix?? //OP IA-TYPE #define OPIA1_LB 0xA1 //rd b= [rs1+rs2] // -- MEM loads/access #define OPIA2_LH 0xA2 //rd h= [rs1+rs2] #define OPIA4_LW 0xA4 //rd w= [rs1+rs2] #define OPIAB_LBU 0xAB //rd ub= [rs1+rs2] #define OPIAD_LHU 0xAD //rd uh= [rs1+rs2] //OP I4-TYPE #define OPI4F_JALR 0x4F // -- indirects, system #define OPI42_ECALL 0x42 #define OPI48_EBREAK 0x48 #define OPI40_FENCE 0x40 //NOP=ignored //0 #define OPI46_IGOTO 0x46 //pseudo //JALR //JR //96 ??? #define OPI4C_ICALL 0x4C //pseudo //JALR //9C ??? #define OPI44_RET 0x44 //pseudo //OP IE-TYPE #define OPIEC_FCALL 0xEC //pseudo //CALL //AUIPC+JALR // -- FAR MEM loads, symbols, calls #define OPIEE_FTAIL 0xEE //pseudo //TAIL //AUIPC+JALR //E6 ?? #define OPIEA_LA 0xEA //TODO pseudo 16 bit (defacto dtto k LI 16bit) #define OPIEF_LA 0xEF //TODO pseudo //auipc combined (fusion)??? #define OPIE1_LB 0xE1 //TODO pseudo //auipc combined (fusion)??? #define OPIE2_LH 0xE2 //TODO pseudo //auipc combined (fusion)??? #define OPIE4_LW 0xE4 //TODO pseudo //auipc combined (fusion)??? //OP S5-TYPE #define OPS51_WB 0x51 //SB //[rs1+rs2] b= rd // -- MEM writes/saves #define OPS52_WH 0x52 //SH //[rs1+rs2] h= rd #define OPS54_WW 0x54 //SW //[rs1+rs2] w= rd //OP SF-TYPE #define OPSF1_WB 0xF1 //TODO pseudo //auipc combined (fusion)??? // -- FAR MEM writes/flushes #define OPSF2_WH 0xF2 //TODO pseudo //auipc combined (fusion)??? #define OPSF4_WW 0xF4 //TODO pseudo //auipc combined (fusion)??? #define OPSFF_INVALID 0xFF //TODO invalid instruction in empty flash ??? or NOP ??? //OP SB-TYPE #define OPSB1_BLT 0xB1 // if (rs1 < rs2) // -- branches #define OPSB2_BLE 0xB2 //pseudo // if (rs1 <= rs2) #define OPSB3_BNE 0xB3 // if (rs1 != rs2) #define OPSB4_BEQ 0xB4 // if (rs1 == rs2) #define OPSB5_BGE 0xB5 // if (rs1 >= rs2) #define OPSB6_BGT 0xB6 //pseudo // if (rs1 > rs2) #define OPSBA_BLTU 0xBA // if (rs1 u< rs2) #define OPSBB_BLEU 0xBB //pseudo // if (rs1 u<= rs2) #define OPSBC_BGEU 0xBC // if (rs1 u>= rs2) #define OPSBD_BGTU 0xBD //pseudo // if (rs1 u> rs2) //OP S8-TYPE #define OPS81_BLTZ 0x81 //pseudo // if (rs1 < 0) // -- branches by 0 #define OPS82_BLEZ 0x82 //pseudo // if (rs1 <= 0) #define OPS83_BNEZ 0x83 //pseudo // if (rs1 != 0) #define OPS84_BEQZ 0x84 //pseudo // if (rs1 == 0) #define OPS85_BGEZ 0x85 //pseudo // if (rs1 >= 0) #define OPS86_BGTZ 0x86 //pseudo // if (rs1 > 0) //OP U7-TYPE - in fact 20bit immediate !!! #define OPU71_LUI 0x71 // -- FAR fusions, jumps, calls #define OPU7A_AUIPC 0x7A #define OPU7F_JAL 0x7F //OP U6-TYPE #define OPU66_GOTO 0x66 //pseudo //JAL //J #define OPU6C_CALL 0x6C //pseudo //JAL //------------------------------------------------------------------------------------------------------ // assembly instructions usage stats // https://www.reddit.com/r/asm/comments/dddn4g/assembly_instruction_use_statistics/ // // simplified BIT-manipulation extensions !!! // https://github.com/riscv/riscv-bitmanip/blob/main-history/bitmanip-draft.pdf // // ALL THIS MUST BE IMPLEMENTABLE BY MACROS IN RISC-V !!! // MORE PRACTICAL PSEUDO/FUSIONS (=optimized) // https://www.strchr.com/x86_machine_code_statistics // PHB PHH PHW //stack //pseudo fusions? = addi sp, sp, -N; wN rx, 0(sp); // PLB PLH PLW //stack //pseudo fusions? = lN rx, 0(sp); addi sp, sp, N; // or support arbitrary PH/PL of number of bytes !!! // PUSH reg // PULL reg // PUSH reg, cnt - push reg + cnt others // PULL reg, cnt // COPY size, from, to - block move ??? // MOVB, MOVM ??? // COPY to, from, size - ??? // SWAP to, reg - ??? swap 16bit words in reg // RBIT, REV - reverse bits order ?? interesting, expensive, fun //https://codegolf.stackexchange.com/questions/36213/reverse-bit-order-of-32-bit-integers?page=2&tab=scoredesc#tab-top //http://netghost.narod.ru/gff/graphics/book/ch06_04.htm //******************************************************************************************** // HLA (ASLIX) support for EASIER DISASSEMBLY OF BINARIES !!! // - this is only WILD DRAFT HERE ... // - HLA opcodes may be used ONLY/MAINLY as NOP MARKERS for assiseted dissassembly while debugging // REM lenght, "comment" (for quick code written in monitor into RAM memory WITH COMMENTS !!) // // IF // ELSE // ( ELSIF ) // ENDIF // LOOP[IF] // AGAIN[IF] // BREAK // CONTINUE ?? isnt this AGAIN ?? // PROC or FUNC // ENDPROC or ENDFUNC