2024-10-04 23:41:10 +00:00
|
|
|
/* 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,
|
|
|
|
};
|
|
|
|
|
2024-10-09 16:08:58 +00:00
|
|
|
/* 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,
|
|
|
|
};
|
|
|
|
|
2024-10-04 23:41:10 +00:00
|
|
|
/* 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;
|
|
|
|
};
|
2024-10-09 16:08:58 +00:00
|
|
|
/* 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;
|
|
|
|
};
|
2024-10-04 23:41:10 +00:00
|
|
|
} __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__ */
|