143 lines
3.4 KiB
C
143 lines
3.4 KiB
C
|
/* 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__ */
|