Skip to content
Permalink
309c13ab73
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
421 lines (408 sloc) 7.33 KB
/*
mipsivm - MIPS Interpreting Virtual Machine
Copyright 2018-2020, Yaotian "Zero" Tang. All rights reserved.
This file defines instructions of MIPS.
This program is distributed in the hope that it will be useful, but
without any warranty (no matter implied warranty or merchantability
or fitness for a particular purpose, etc.).
File Location: /include/vcpu.c
*/
#include <midef.h>
// Definition of Instruction
typedef union _mips_instruction
{
// R-Format Instruction
struct
{
u32 funct:6;
u32 shamt:5;
u32 rd:5;
u32 rt:5;
u32 rs:5;
u32 op:6;
}r;
// I-Format Instruction
struct
{
u32 imm:16;
u32 rt:5;
u32 rs:5;
u32 op:6;
}i;
// J-Format Instruction
struct
{
u32 addr:26;
u32 op:6;
}j;
// FR-Format Instruction (FPU)
struct
{
u32 funct:6;
u32 fd:5;
u32 fs:5;
u32 ft:5;
u32 fmt:5;
u32 op:6;
}fr;
// FI-Format Instruction (FPU)
struct
{
u32 imm:16;
u32 ft:5;
u32 fmt:5;
u32 op:6;
}fi;
u32 value;
}mips_instruction,*mips_instruction_p;
// Classify Instructions
#define unknown 0
#define r_format 1
#define i_format 2
#define j_format 3
#define f_format 4
// Registers
#define mips_gpr_zero 0x00
#define mips_gpr_at 0x01
#define mips_gpr_v0 0x02
#define mips_gpr_v1 0x03
#define mips_gpr_a0 0x04
#define mips_gpr_a1 0x05
#define mips_gpr_a2 0x06
#define mips_gpr_a3 0x07
#define mips_gpr_t0 0x08
#define mips_gpr_t1 0x09
#define mips_gpr_t2 0x0A
#define mips_gpr_t3 0x0B
#define mips_gpr_t4 0x0C
#define mips_gpr_t5 0x0D
#define mips_gpr_t6 0x0E
#define mips_gpr_t7 0x0F
#define mips_gpr_s0 0x10
#define mips_gpr_s1 0x11
#define mips_gpr_s2 0x12
#define mips_gpr_s3 0x13
#define mips_gpr_s4 0x14
#define mips_gpr_s5 0x15
#define mips_gpr_s6 0x16
#define mips_gpr_s7 0x17
#define mips_gpr_t8 0x18
#define mips_gpr_t9 0x19
#define mips_gpr_k0 0x1A
#define mips_gpr_k1 0x1B
#define mips_gpr_gp 0x1C
#define mips_gpr_sp 0x1D
#define mips_gpr_fp 0x1E
#define mips_gpr_ra 0x1F
#if defined(_mips_hvm)
u8 mips_opcode_class[64]=
{
r_format, // 0x00
unknown, // 0x01
j_format, // 0x02
j_format, // 0x03
i_format, // 0x04
i_format, // 0x05
i_format, // 0x06
i_format, // 0x07
i_format, // 0x08
i_format, // 0x09
i_format, // 0x0A
i_format, // 0x0B
i_format, // 0x0C
i_format, // 0x0D
i_format, // 0x0E
i_format, // 0x0F
unknown, // 0x10
f_format, // 0x11
unknown, // 0x12
unknown, // 0x13
unknown, // 0x14
unknown, // 0x15
unknown, // 0x16
unknown, // 0x17
unknown, // 0x18
unknown, // 0x19
unknown, // 0x1A
unknown, // 0x1B
unknown, // 0x1C
unknown, // 0x1D
unknown, // 0x1E
unknown, // 0x1F
i_format, // 0x20
i_format, // 0x21
i_format, // 0x22
i_format, // 0x23
i_format, // 0x24
i_format, // 0x25
i_format, // 0x26
unknown, // 0x27
i_format, // 0x28
i_format, // 0x29
i_format, // 0x2A
i_format, // 0x2B
unknown, // 0x2C
unknown, // 0x2D
i_format, // 0x2E
i_format, // 0x2F
i_format, // 0x30
i_format, // 0x31
i_format, // 0x32
i_format, // 0x33
unknown, // 0x34
i_format, // 0x35
i_format, // 0x36
unknown, // 0x37
i_format, // 0x38
i_format, // 0x39
i_format, // 0x3A
unknown, // 0x3B
unknown, // 0x3C
i_format, // 0x3D
i_format, // 0x3E
unknown // 0x3F
};
// Name of General Purpose Registers (GPR)
char* mips_gpr_string[32]=
{
"$zero", // 0x00
"$at", // 0x01
"$v0", // 0x02
"$v1", // 0x03
"$a0", // 0x04
"$a1", // 0x05
"$a2", // 0x06
"$a3", // 0x07
"$t0", // 0x08
"$t1", // 0x09
"$t2", // 0x0A
"$t3", // 0x0B
"$t4", // 0x0C
"$t5", // 0x0D
"$t6", // 0x0E
"$t7", // 0x0F
"$s0", // 0x10
"$s1", // 0x11
"$s2", // 0x12
"$s3", // 0x13
"$s4", // 0x14
"$s5", // 0x15
"$s6", // 0x16
"$s7", // 0x17
"$t8", // 0x18
"$t9", // 0x19
"$k0", // 0x1A
"$k1", // 0x1B
"$gp", // 0x1C
"$sp", // 0x1D
"$fp", // 0x1E
"$ra" // 0x1F
};
char* mips_cpu_opcode_string[64]=
{
null, // 0x00
null, // 0x01
"j", // 0x02
"jal", // 0x03
"beq", // 0x04
"bne", // 0x05
"blez", // 0x06
"bgtz", // 0x07
"addi", // 0x08
"addiu", // 0x09
"slti", // 0x0A
"sltiu", // 0x0B
"andi", // 0x0C
"ori", // 0x0D
"xori", // 0x0E
"lui", // 0x0F
null, // 0x10
null, // 0x11
null, // 0x12
null, // 0x13
null, // 0x14
null, // 0x15
null, // 0x16
null, // 0x17
null, // 0x18
null, // 0x19
null, // 0x1A
null, // 0x1B
null, // 0x1C
null, // 0x1D
null, // 0x1E
null, // 0x1F
"lb", // 0x20
"lh", // 0x21
"lwl", // 0x22
"lw", // 0x23
"lbu", // 0x24
"lhu", // 0x25
"lwr", // 0x26
null, // 0x27
"sb", // 0x28
"sh", // 0x29
"swl", // 0x2A
"sw", // 0x2B
null, // 0x2C
null, // 0x2D
"swr", // 0x2E
"cache", // 0x2F
"ll", // 0x30
"lwc1", // 0x31
"lwc2", // 0x32
"pref", // 0x33
null, // 0x34
"ldc1", // 0x35
"ldc2", // 0x36
null, // 0x37
"sc", // 0x38
"swc1", // 0x39
"swc2", // 0x3A
null, // 0x3B
null, // 0x3C
"sdc1", // 0x3D
"sdc2", // 0x3E
null // 0x3F
};
char* mips_cpu_funct_string[64]=
{
"sll", // 0x00
null, // 0x01
"srl", // 0x02
"sra", // 0x03
"sllv", // 0x04
null, // 0x05
"srlv", // 0x06
"srav", // 0x07
"jr", // 0x08
"jalr", // 0x09
"movz", // 0x0A
"movn", // 0x0B
"syscall", // 0x0C
"break", // 0x0D
null, // 0x0E
"sync", // 0x0F
"mfhi", // 0x10
"mthi", // 0x11
"mflo", // 0x12
"mtlo", // 0x13
null, // 0x14
null, // 0x15
null, // 0x16
null, // 0x17
"mult", // 0x18
"multu", // 0x19
"div", // 0x1A
"divu", // 0x1B
null, // 0x1C
null, // 0x1D
null, // 0x1E
null, // 0x1F
"add", // 0x20
"addu", // 0x21
"sub", // 0x22
"subu", // 0x23
"and", // 0x24
"or", // 0x25
"xor", // 0x26
"nor", // 0x27
null, // 0x28
null, // 0x29
"slt", // 0x2A
"sltu", // 0x2B
null, // 0x2C
null, // 0x2D
null, // 0x2E
null, // 0x2F
"tge", // 0x30
"tgeu", // 0x31
"tlt", // 0x32
"tltu", // 0x33
"teq", // 0x34
null, // 0x35
"tne", // 0x36
null, // 0x37
null, // 0x38
null, // 0x39
null, // 0x3A
null, // 0x3B
null, // 0x3C
null, // 0x3D
null, // 0x3E
null // 0x3F
};
char* mips_fpu_funct_string[64]=
{
"add.f", // 0x00
"sub.f", // 0x01
"mul.f", // 0x02
"div.f", // 0x03
"sqrt.f", // 0x04
"abs.f", // 0x05
"mov.f", // 0x06
"neg.f", // 0x07
null, // 0x08
null, // 0x09
null, // 0x0A
null, // 0x0B
"round.w.f", // 0x0C
"trunc.w.f", // 0x0D
"ceil.w.f", // 0x0E
"floor.w.f", // 0x0F
null, // 0x10
null, // 0x11
"movz.f", // 0x12
"movn.f", // 0x13
null, // 0x14
null, // 0x15
null, // 0x16
null, // 0x17
null, // 0x18
null, // 0x19
null, // 0x1A
null, // 0x1B
null, // 0x1C
null, // 0x1D
null, // 0x1E
null, // 0x1F
"cvt.s.f", // 0x20
"cvt.d.f", // 0x21
null, // 0x22
null, // 0x23
"cvt.w.f", // 0x24
null, // 0x25
null, // 0x26
null, // 0x27
null, // 0x28
null, // 0x29
null, // 0x2A
null, // 0x2B
null, // 0x2C
null, // 0x2D
null, // 0x2E
null, // 0x2F
"c.f.f", // 0x30
"c.un.f", // 0x31
"c.eq.f", // 0x32
"c.ueq.f", // 0x33
"c.olt.f", // 0x34
"c.ult.f", // 0x35
"c.ole.f", // 0x36
"c.ule.f", // 0x37
"c.sf.f", // 0x38
"c.ngle.f", // 0x39
"c.seq.f", // 0x3A
"c.ngl.f", // 0x3B
"c.lt.f", // 0x3C
"c.nge.f", // 0x3D
"c.le.f", // 0x3E
"c.ngt.f" // 0x3F
};
#else
extern u8* mips_opcode_class;
extern char** mips_gpr_string;
extern char** mips_cpu_opcode_string;
extern char** mips_cpu_funct_string;
extern char** mips_fpu_funct_string;
#endif