diff options
| author | Freya Murphy <freya@freyacat.org> | 2024-10-09 12:08:58 -0400 |
|---|---|---|
| committer | Freya Murphy <freya@freyacat.org> | 2024-10-09 12:08:58 -0400 |
| commit | 720b95b5d993caacae420b24dcf8a39a97b31871 (patch) | |
| tree | 39e94ad23c57d343733025b4e914cc762fb1a5f1 /include/mips.h | |
| parent | add pseudo instructions test (diff) | |
| download | mips-720b95b5d993caacae420b24dcf8a39a97b31871.tar.gz mips-720b95b5d993caacae420b24dcf8a39a97b31871.tar.bz2 mips-720b95b5d993caacae420b24dcf8a39a97b31871.zip | |
add mips1 and mips32r2 isa definitions
Diffstat (limited to 'include/mips.h')
| -rw-r--r-- | include/mips.h | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/include/mips.h b/include/mips.h new file mode 100644 index 0000000..8155eb7 --- /dev/null +++ b/include/mips.h @@ -0,0 +1,220 @@ +/* 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, +}; + +/* all mips fp registers $f0-$f31 */ +enum mips32_fp_register { + MIPS32_REG_F0 = 0, + MIPS32_REG_F1 = 1, + MIPS32_REG_F2 = 2, + MIPS32_REG_F3 = 3, + MIPS32_REG_F4 = 4, + MIPS32_REG_F5 = 5, + MIPS32_REG_F6 = 6, + MIPS32_REG_F7 = 7, + MIPS32_REG_F8 = 8, + MIPS32_REG_F9 = 9, + MIPS32_REG_F10 = 10, + MIPS32_REG_F11 = 11, + MIPS32_REG_F12 = 12, + MIPS32_REG_F13 = 13, + MIPS32_REG_F14 = 14, + MIPS32_REG_F15 = 15, + MIPS32_REG_F16 = 16, + MIPS32_REG_F17 = 17, + MIPS32_REG_F18 = 18, + MIPS32_REG_F19 = 19, + MIPS32_REG_F20 = 20, + MIPS32_REG_F21 = 21, + MIPS32_REG_F22 = 22, + MIPS32_REG_F23 = 23, + MIPS32_REG_F24 = 24, + MIPS32_REG_F25 = 25, + MIPS32_REG_F26 = 26, + MIPS32_REG_F27 = 27, + MIPS32_REG_F28 = 28, + MIPS32_REG_F29 = 29, + MIPS32_REG_F30 = 30, + MIPS32_REG_F31 = 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; + }; + /* coprocessor */ + struct { + uint32_t : 21; + uint32_t cfunct : 5; + uint32_t : 6; + }; + /* flags */ + struct { + // 6 bit + uint32_t : 5; + uint32_t sc : 1; // interrupt + // 5 bit + uint32_t rv : 1; // rotate variable + uint32_t : 3; + uint32_t hb : 1; // hazard barrier + // 5 bit + uint32_t : 5; + // 5 bit + uint32_t tf : 1; // true false + uint32_t nd : 1; // + uint32_t cc : 3; // code + // 5 bit + uint32_t r : 1; // rotate + uint32_t : 3; + uint32_t c0 : 1; // cop0 + // 6 bit + uint32_t : 6; + }; + /* break code */ + struct { + uint32_t : 6; + uint32_t code : 20; + uint32_t : 6; + }; + /* floating point */ + struct { + uint32_t : 6; + uint32_t fd : 5; + uint32_t fs : 5; + uint32_t ft : 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__ */ |