因为想在不借助 EJTAG 的情况下来验证 RTOS, 所以最近恨下心来想抽空写一个 Au1200 的模拟器(我一直觉得 gxemul 和 Simics 都不是很好用),于是先根据《See MIPS Run》一书总结了一下 MIPS 的编码格式(附带说一句,网上搜出的文章以及 Hennessy 的书都说 MIPS 只有 R, I, J 三种编码形式,若仔细看看新的 MIPS32 文档或《See MIPS Run》一书的第八章,便可以知道这种说法已不适用于新的情况)。
事实上,就我对《See MIPS Run》一书第一版和第二版的总结,当前的 MIPS 编码格式总计九种,分别为:
1) 31~26, 25~00, 即 6+26 格式;
2) 31~26, 25~06, 05~00, 即 6+20+6 格式;
3) 31~26, 25~21, 20~16, 15~00, 即 6+5+5+16 格式;
4) 31~26, 25~11, 10~06, 05~00, 即 6+15+5+6 格式;
5) 31~26, 25~21, 20~18, 17~16, 15~00, 即 6+5+3+2+16 格式;
6) 31~26, 25~21, 20~16, 15~06, 05~00, 即 6+5+5+10+6 格式;
7) 31~26, 25~21, 20~16, 15~11, 10~06, 05~00, 即 6+5+5+5+5+6 格式;
8) 31~26, 25~21, 20~18, 17~16, 15~11, 10~06, 05~00, 即 6+5+3+2+5+5+6 格式;
9) 31~26, 25~21, 20~16, 15~11, 10~08, 07~06, 05~00, 即 6+5+5+5+3+2+6 格式。
具体定义代码如下:
#define FIELD(name,ebit,sbit) name:(ebit-sbit+1)
//3126 2500, Instruction format 1
typedef struct {
unsigned long FIELD(target,25,0);
unsigned long FIELD(op,31,26);
} MIPS_CFMT1;
//3126 2506 0500, Instruction format 2
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(code,25,6);
unsigned long FIELD(op,31,26);
} MIPS_CFMT2;
//3126 2521 2016 1500
typedef struct {
unsigned long FIELD(off,15,0);
unsigned long FIELD(rt,20,16);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT3;
//3126 2511 1006 0500
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(x,10,6);
unsigned long FIELD(code,25,11);
unsigned long FIELD(op,31,26);
} MIPS_CFMT4;
//3126 2521 2018 1716 1500
typedef struct {
unsigned long FIELD(off,15,0);
unsigned long FIELD(N0,17,16);
unsigned long FIELD(N,20,18);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT5;
//3126 2521 2016 1506 0500
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(x,15,6);
unsigned long FIELD(rt,20,16);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT6;
//3126 2521 2016 1511 1006 0500
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(shft,10,6);
unsigned long FIELD(rd,15,11);
unsigned long FIELD(rw,20,16);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT7;
//3126 2521 2018 1716 1511 1006 0500
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(shft,10,6);
unsigned long FIELD(rd,15,11);
unsigned long FIELD(N0,17,16);
unsigned long FIELD(N,20,18);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT8;
//3126 2521 2016 1511 1008 0706 0500
typedef struct {
unsigned long FIELD(ext,5,0);
unsigned long FIELD(rx,7,6);
unsigned long FIELD(M,10,8);
unsigned long FIELD(fs,15,11);
unsigned long FIELD(ft,20,16);
unsigned long FIELD(rs,25,21);
unsigned long FIELD(op,31,26);
} MIPS_CFMT9;
typedef union {
unsigned long code;
MIPS_CFMT1 fmt1;
MIPS_CFMT2 fmt2;
MIPS_CFMT3 fmt3;
MIPS_CFMT4 fmt4;
MIPS_CFMT5 fmt5;
MIPS_CFMT6 fmt6;
MIPS_CFMT7 fmt7;
MIPS_CFMT8 fmt8;
MIPS_CFMT9 fmt9;
} MIPS_INSTR;
#define FMT_3126_2500 fmt1
#define FMT_3126_2506_0500 fmt2
#define FMT_3126_2521_2016_1500 fmt3
#define FMT_3126_2511_1006_0500 fmt4
#define FMT_3126_2521_2018_1716_1500 fmt5
#define FMT_3126_2521_2016_1506_0500 fmt6
#define FMT_3126_2521_2016_1511_1006_0500 fmt7
#define FMT_3126_2521_2018_1716_1511_1006_0500 fmt8
#define FMT_3126_2521_2016_1511_1008_0706_0500 fmt9