diff options
Diffstat (limited to '')
-rw-r--r-- | include/mips32.h | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/include/mips32.h b/include/mips32.h new file mode 100644 index 0000000..e2b86b7 --- /dev/null +++ b/include/mips32.h @@ -0,0 +1,142 @@ +/* Copyright (c) 2024 Freya Murphy */ + +#ifndef __MIPS32_H__ +#define __MIPS32_H__ + +#include <stddef.h> +#include <stdint.h> +#include <mlimits.h> + +/* all mips registers $0-$31 */ +enum mips32_register { + MIPS32_REG_ZERO = 0, + MIPS32_REG_AT = 1, + MIPS32_REG_V0 = 2, + MIPS32_REG_V1 = 3, + MIPS32_REG_A0 = 4, + MIPS32_REG_A1 = 5, + MIPS32_REG_A2 = 6, + MIPS32_REG_A3 = 7, + MIPS32_REG_T0 = 8, + MIPS32_REG_T1 = 9, + MIPS32_REG_T2 = 10, + MIPS32_REG_T3 = 11, + MIPS32_REG_T4 = 12, + MIPS32_REG_T5 = 13, + MIPS32_REG_T6 = 14, + MIPS32_REG_T7 = 15, + MIPS32_REG_S0 = 16, + MIPS32_REG_S1 = 17, + MIPS32_REG_S2 = 18, + MIPS32_REG_S3 = 19, + MIPS32_REG_S4 = 20, + MIPS32_REG_S5 = 21, + MIPS32_REG_S6 = 22, + MIPS32_REG_S7 = 23, + MIPS32_REG_T8 = 24, + MIPS32_REG_T9 = 25, + MIPS32_REG_K0 = 26, + MIPS32_REG_K1 = 27, + MIPS32_REG_GP = 28, + MIPS32_REG_SP = 29, + MIPS32_REG_FP = 30, + MIPS32_REG_RA = 31, +}; + +/* mips instruction */ +union mips32_instruction { + /* raw ins */ + uint32_t raw : 32; + /* register type */ + struct { + uint32_t funct : 6; + uint32_t shamt : 5; + uint32_t rd : 5; + uint32_t rt : 5; + uint32_t rs : 5; + uint32_t op : 6; + }; + /* immediate type */ + struct { + uint32_t immd : 16; + uint32_t : 16; + }; + /* jump type */ + struct { + uint32_t target : 26; + uint32_t : 6; + }; + /* branch compact */ + struct { + int32_t offs26 : 26; + uint32_t : 6; + }; + /* branch */ + struct { + int32_t offset : 16; + uint32_t bfunct : 5; + uint32_t : 11; + }; +} __attribute__((packed)); + +/// grammer syntax: +/// +/// ... the grammer takes entries parsed from the instruction, +/// and updates the instructions with values based on the type +/// of entry. i.e. immd would require a immd in the next argument, +/// and update the low 16bits of the instruction. +/// +/// GRAMMER -> ENTRIES +/// GRAMMER -> ε +/// ENTRIES -> ENTRIES, ENTRY +/// ENTRY -> rd // i.e. $at +/// ENTRY -> rs +/// ENTRY -> rt +/// ENTRY -> immd // i.e. 0x80 +/// ENTRY -> offset // i.e. main (16bits) +/// ENTRY -> offest(base) // i.e. 4($sp) +/// ENTRY -> target // i.e. main (28bits shifted) +/// +/// // grammer entries are always defined onto themselves... meaning the +/// // name of their type directly corresponds to the mips field in the +/// // instruction +/// +/// pseudo grammer syntax: +/// +/// ... psuedo entries represents what values should be placed where +/// in each of the pseudo instructions. psuedo grammer is extended such +/// that hardcoded values can be returned. i.e. setting rt=$at +/// +/// GRAMMER -> ENTRIES +/// GRAMMER -> ε +/// ENTREIS -> ENTRIES, ENTRYSET +/// ENTRYSET -> ENTRY | SET +/// SET -> ENTRY = <REGISTER> +/// ENTRY -> <GRAMMER: ENTRY> // i.e. any valid entry from grammer synax +/// ENTRY -> hi // high 16bits of <target> into <immd> +/// ENTRY -> lo // low 16bits of <target> into <immd> + +/* mips grammer */ +struct mips32_grammer { + // the name of the ins + char *name; + // the grammer of the ins + char *grammer; + // the index of the ins (if real) + int enum_index; + + // for pseudo instructions only + int pseudo_len; + struct mips32__pseudo_grammer { + // what instruction is this + // part in the pseudo instruction + int enum_index; + // what parts of the instruction + // to update with values from + // grammer + char *update; + + } pseudo_grammer[MAX_ARG_LENGTH]; +}; + +#endif /* __MIPS32_H__ */ |