ghidra/Ghidra/Processors/MIPS/data/languages/mips16.sinc

765 lines
28 KiB
Plaintext

################
#
# MIPS16e
#
# From MIPS32 Architecture for PRogrammers Volume IV-a:
# The MIPS16e Application Specific Extension to the MIPS32
# Architecture.
#
# Document #: MD00076 Rev 2.63 July 16, 2013
#
################
define token m16instr (16)
m16_op=(11,15)
m16_i_imm=(0,4)
m16_rx=(8,10)
m16_rxa=(8,10)
m16_ri_imm=(0,4)
m16_ri_z=(5,7)
m16_ry=(5,7)
m16_rya=(5,7)
m16_rr_f=(0,4)
m16_rr_nd=(7,7)
m16_rr_l=(6,6)
m16_rr_ra=(5,5)
m16_rr_z=(5,7)
m16_rri_imm=(0,4)
m16_rz=(2,4)
m16_rza=(2,4)
m16_rrr_f=(0,1)
m16_rria_f=(4,4)
m16_rria_imm=(0,3)
m16_rria_simm=(0,3) signed
m16_shft_sa=(2,4)
m16_shft_f=(0,1)
m16_i8_f=(8,10)
m16_i8_imm=(0,4)
m16_is8_imm=(0,7) signed
m16_mv_rz=(0,2)
m16_mv_rza=(0,2)
m16_i8_rz=(5,7)
m16_i8_r32=(0,4)
m16_i8_r32a=(0,4)
m16_i8_r32_20=(5,7)
m16_i8_r32_43=(3,4)
m16_i8_svrs=(8,10)
m16_i8_sw=(8,10)
m16_iu8_imm=(0,7)
m16_b_imm=(0,4)
m16_b_z=(5,10)
m16_cb_z=(5,7)
m16_b_off=(0,10) signed
m16_cb_off=(0,7) signed
m16_svrs_s=(7,7)
m16_svrs_ra=(6,6)
m16_svrs_s0=(5,5)
m16_svrs_s1=(4,4)
m16_svrs_frame=(0,3)
m16_ext_val=(0,10)
m16_tgt_1500=(0,15)
m16_tgt_2521=(0,4)
m16_tgt_2016=(5,9)
m16_jal=(10,10)
m16_code=(5,10)
;
attach variables [ m16_rx m16_ry m16_rz m16_mv_rz ]
[ s0 s1 v0 v1 a0 a1 a2 a3 ];
attach variables [ ext_m16r32 m16_i8_r32 ] [
zero at v0 v1 a0 a1 a2 a3
t0 t1 t2 t3 t4 t5 t6 t7
s0 s1 s2 s3 s4 s5 s6 s7
t8 t9 k0 k1 gp sp s8 ra
];
@ifdef MIPS64
attach variables [ m16_rxa m16_rya m16_rza m16_mv_rza]
[ s0_lo s1_lo v0_lo v1_lo a0_lo a1_lo a2_lo a3_lo ];
attach variables [ ext_m16r32a m16_i8_r32a ] [
zero_lo at_lo v0_lo v1_lo a0_lo a1_lo a2_lo a3_lo
t0_lo t1_lo t2_lo t3_lo t4_lo t5_lo t6_lo t7_lo
s0_lo s1_lo s2_lo s3_lo s4_lo s5_lo s6_lo s7_lo
t8_lo t9_lo k0_lo k1_lo gp_lo sp_lo s8_lo ra_lo
];
RZ: m16_rz is m16_rz { export m16_rz; }
@else # !MIPS64
attach variables [ m16_rxa m16_rya m16_rza m16_mv_rza ]
[ s0 s1 v0 v1 a0 a1 a2 a3 ];
attach variables [ ext_m16r32a m16_i8_r32a ] [
zero at v0 v1 a0 a1 a2 a3
t0 t1 t2 t3 t4 t5 t6 t7
s0 s1 s2 s3 s4 s5 s6 s7
t8 t9 k0 k1 gp sp s8 ra
];
RZ: is epsilon {}
@endif # MIPS64
RX: m16_rx is m16_rx { export m16_rx; }
RX32: m16_rx is m16_rx & m16_rxa { export m16_rxa; }
RY32: m16_ry is m16_ry & m16_rya { export m16_rya; }
RZ32: m16_rz is m16_rz & m16_rza { export m16_rza; }
#RMZ32: m16_mv_rz is m16_mv_rz & m16_mv_rza { export m16_mv_rza; }
#R32M: ext_m16r32 is ext_m16r32 & ext_m16r32a { export ext_m16r32a; }
#R32I: m16_i8_r32 is m16_i8_r32 & m16_i8_r32a { export m16_i8_r32a; }
attach names [ ext_svrs_sreg][
_ "s0" "s1" "s0-s1"
"s2" "s0,s2" "s1-s2" "s0-s2"
"s2-s3" "s0,s2-s3" "s1-s3" "s0-s3"
"s2-s4" "s0,s2-s4" "s1-s4" "s0-s4"
"s2-s5" "s0,s2-s5" "s1-s5" "s0-s5"
"s2-s6" "s0,s2-s6" "s1-s6" "s0-s6"
"s2-s7" "s0,s2-s7" "s1-s7" "s0-s7"
"s2-s8" "s0,s2-s8" "s1-s8" "s0-s8"
];
Abs26_m16: reloc is m16_tgt_1500 & ext_tgt_2016 & ext_tgt_2521 [ reloc=((inst_start+4) $and 0xfffffffff0000000)+4*(m16_tgt_1500 | (ext_tgt_2016 << 16) | (ext_tgt_2521 << 21)); ] { export *:$(ADDRSIZE) reloc; }
Rel16_m16: reloc is ext_is_ext=1 & m16_b_z=0 & m16_b_imm & ext_value_1005 & ext_value_1511s [ reloc=inst_start+4+2*((ext_value_1511s << 11) | (ext_value_1005 << 5) | m16_b_imm); ] { export *:$(ADDRSIZE) reloc; }
Rel16_m16: reloc is ext_is_ext=0 & m16_b_off [ reloc=inst_start+2+2*m16_b_off; ] { export *:$(ADDRSIZE) reloc; }
CRel16_m16: reloc is ext_is_ext=1 & m16_cb_z=0 & m16_b_imm & ext_value_1005 & ext_value_1511s [ reloc=inst_start+4+2*((ext_value_1511s << 11) | (ext_value_1005 << 5) | m16_b_imm); ] { export *:$(ADDRSIZE) reloc; }
CRel16_m16: reloc is ext_is_ext=0 & m16_cb_off [ reloc=inst_start+2+2*m16_cb_off; ] { export *:$(ADDRSIZE) reloc; }
:^instruction is ISA_MODE=1 & RELP=1 & m16_op=0b11110 & ext_done=0 & ext_isjal=0 & m16_ext_val; instruction [ext_value=m16_ext_val; ext_is_ext=1; ext_done=1; ] { build instruction; }
:^instruction is ISA_MODE=1 & RELP=1 & m16_op=0b00011 & ext_done=0 & ext_isjal=0 & m16_jal & m16_tgt_2016 & m16_tgt_2521; instruction [ext_tgt_2016=m16_tgt_2016; ext_tgt_2521=m16_tgt_2521; ext_tgt_x=m16_jal; ext_isjal=1; ext_done=1; ] { build instruction; }
EXT_I: val is m16_i_imm [ val = m16_i_imm << 2; ] { export *[const]:2 val; }
EXT_IS0: val is m16_i_imm [ val = m16_i_imm << 0; ] { export *[const]:2 val; }
EXT_IS1: val is m16_i_imm [ val = m16_i_imm << 1; ] { export *[const]:2 val; }
EXT_RI: val is ext_value_1511 & ext_value_1005 & m16_ri_imm [val = (ext_value_1511 << 11) | (ext_value_1005 << 5) | m16_ri_imm; ] { export *[const]:2 val; }
EXT_RRIA: val is ext_is_ext=1 & ext_value_1411s & ext_value_1004 & m16_rria_imm [ val=(ext_value_1411s << 11) | (ext_value_1004 << 4) | m16_rria_imm; ] { export *[const]:2 val; }
EXT_RRIA: m16_rria_simm is ext_is_ext=0 & m16_rria_simm { export *[const]:2 m16_rria_simm; }
EXT_IS8: val is ext_is_ext=1 & ext_value_1511s & ext_value_1005 & m16_i8_imm [val=(ext_value_1511s << 11) | (ext_value_1005 << 5) | m16_i8_imm; ] { export *[const]:2 val; }
EXT_IS8: m16_is8_imm is ext_is_ext=0 & m16_is8_imm { export *[const]:2 m16_is8_imm; }
EXT_IS8L3: val is ext_is_ext=0 & ext_value_1511 & ext_value_1005 & m16_is8_imm [val = m16_is8_imm << 3; ] { export *[const]:2 val; }
EXT_IU8: val is ext_is_ext=1 & ext_value_1511 & ext_value_1005 & m16_i8_imm [val = (ext_value_1511 << 11) | (ext_value_1005 << 5) | m16_i8_imm; ] { export *[const]:2 val; }
EXT_IU8: val is ext_is_ext=0 & m16_iu8_imm [val = m16_iu8_imm << 2; ] { export *[const]:2 val; }
EXT_LIU8: val is ext_is_ext=1 & m16_ri_z=0 & ext_value_1511 & ext_value_1005 & m16_i8_imm [val = (ext_value_1511 << 11) | (ext_value_1005 << 5) | m16_i8_imm; ] { export *[const]:2 val; }
EXT_LIU8: m16_iu8_imm is ext_is_ext=0 & m16_iu8_imm { export *[const]:2 m16_iu8_imm; }
EXT_SHIFT: ext_value_sa40 is ext_is_ext=1 & ext_value_saz=0 & m16_shft_sa=0 & ext_value_sa40 { export *[const]:1 ext_value_sa40;}
EXT_SHIFT: val is ext_is_ext=0 & m16_shft_sa=0 [val = 8; ] { export *[const]:1 val;}
EXT_SHIFT: m16_shft_sa is ext_is_ext=0 & m16_shft_sa { export *[const]:1 m16_shft_sa;}
EXT_SET: val is ext_is_ext=1 & m16_ri_z=0 & ext_value_1511 & ext_value_1005 & m16_i8_imm [val = (ext_value_1511 << 11) | (ext_value_1005 << 5) | m16_i8_imm; ] { export *[const]:4 val; }
EXT_SET: m16_iu8_imm is ext_is_ext=0 & m16_iu8_imm { export *[const]:4 m16_iu8_imm; }
OFF_M16: EXT_IS8(m16_rx) is ext_is_ext=1 & EXT_IS8 & m16_rx { tmp:$(REGSIZE) = m16_rx + sext(EXT_IS8); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16: EXT_I(m16_rx) is ext_is_ext=0 & EXT_I & m16_rx { tmp:$(REGSIZE) = m16_rx + zext(EXT_I); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16S0: EXT_IS8(m16_rx) is ext_is_ext=1 & EXT_IS8 & m16_rx { tmp:$(REGSIZE) = m16_rx + sext(EXT_IS8); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16S0: EXT_IS0(m16_rx) is ext_is_ext=0 & EXT_IS0 & m16_rx { tmp:$(REGSIZE) = m16_rx + zext(EXT_IS0); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16S1: EXT_IS8(m16_rx) is ext_is_ext=1 & EXT_IS8 & m16_rx { tmp:$(REGSIZE) = m16_rx + sext(EXT_IS8); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16S1: EXT_IS1(m16_rx) is ext_is_ext=0 & EXT_IS1 & m16_rx { tmp:$(REGSIZE) = m16_rx + zext(EXT_IS1); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16PC: EXT_IS8(pc) is ext_is_ext=1 & m16_i8_rz=0 & EXT_IS8 & pc { tmp:$(REGSIZE) = (inst_start + sext(EXT_IS8)) & 0xFFFFFFFC; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16PC: val(pc) is ext_is_ext=0 & m16_iu8_imm & pc & ext_delay [ val = m16_iu8_imm << 2; ] { tmp:$(REGSIZE) = (inst_start + val - (ext_delay << 1)) & 0xFFFFFFFC; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16SP: EXT_IS8(sp) is ext_is_ext=1 & m16_i8_rz=0 & EXT_IS8 & sp { tmp:$(REGSIZE) = sp + sext(EXT_IS8); tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_M16SP: val(sp) is ext_is_ext=0 & m16_iu8_imm & sp [ val = m16_iu8_imm << 2; ] { tmp:$(REGSIZE) = sp + val; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
EXT_FRAME: val is ext_value_frame=0 & m16_svrs_frame=0 [val = 128; ] {export *[const]:2 val;}
EXT_FRAME: val is ext_value_frame & m16_svrs_frame [val = ((ext_value_frame << 4) | m16_svrs_frame) << 3;] {export *[const]:2 val;}
REGRS_STAT: is ext_value_areg {}
REGRS_STAT: ",a3" is (ext_value_areg=1 | ext_value_areg=5 | ext_value_areg=9 |ext_value_areg=0xd) {
tsp = tsp-4;
MemSrcCast(a3,tsp);
}
REGRS_STAT: ",a2-a3" is (ext_value_areg=2 | ext_value_areg=6 | ext_value_areg=0xa) {
tsp = tsp-4;
MemSrcCast(a3,tsp);
tsp = tsp-4;
MemSrcCast(a2,tsp);
}
REGRS_STAT: ",a1-a3" is (ext_value_areg=3 | ext_value_areg=7) {
tsp = tsp-4;
MemSrcCast(a3,tsp);
tsp = tsp-4;
MemSrcCast(a2,tsp);
tsp = tsp-4;
MemSrcCast(a1,tsp);
}
REGRS_STAT: ",a0-a3" is ext_value_areg=0xB {
tsp = tsp-4;
MemSrcCast(a3,tsp);
tsp = tsp-4;
MemSrcCast(a2,tsp);
tsp = tsp-4;
MemSrcCast(a1,tsp);
tsp = tsp-4;
MemSrcCast(a0,tsp);
}
REST_STAT: is ext_value_areg=0 | ext_value_areg=4 | ext_value_areg=8 | ext_value_areg=0xc | ext_value_areg=0xe {}
REST_STAT: REGRS_STAT is REGRS_STAT {
build REGRS_STAT;
}
REGSV_STAT: is ext_value_areg {}
REGSV_STAT: ",a3" is (ext_value_areg=1 | ext_value_areg=5 | ext_value_areg=9 | ext_value_areg=0xd) {
tsp = tsp-4;
MemDestCast(tsp,a3);
}
REGSV_STAT: ",a2-a3" is (ext_value_areg=2 | ext_value_areg=6 | ext_value_areg=0xa) {
tsp = tsp-4;
MemDestCast(tsp,a3);
tsp = tsp-4;
MemDestCast(tsp,a2);
}
REGSV_STAT: ",a1-a3" is (ext_value_areg=3 | ext_value_areg=7) {
tsp = tsp-4;
MemDestCast(tsp,a3);
tsp = tsp-4;
MemDestCast(tsp,a2);
tsp = tsp-4;
MemDestCast(tsp,a1);
}
REGSV_STAT: ",a0-a3" is ext_value_areg=0xb {
tsp = tsp-4;
MemDestCast(tsp,a3);
tsp = tsp-4;
MemDestCast(tsp,a2);
tsp = tsp-4;
MemDestCast(tsp,a1);
tsp = tsp-4;
MemDestCast(tsp,a0);
}
SAVE_STAT: is ext_value_areg=0 | ext_value_areg=4 | ext_value_areg=8 | ext_value_areg=0xc | ext_value_areg=0xe {}
SAVE_STAT: REGSV_STAT is REGSV_STAT {
build REGSV_STAT;
}
REGSV_BLD1: is ext_value_b2=0 {}
REGSV_BLD1: "a0," is ext_value_b2=1 {
ptr:$(REGSIZE) = sp;
MemDestCast(ptr,a0);
}
REGSV_BLD2: REGSV_BLD1 is REGSV_BLD1 { build REGSV_BLD1; }
REGSV_BLD2: "a0-a1," is ext_value_b3=1 & ext_value_b2=0 & (ext_value_b1=0 | ext_value_b0=0) {
ptr:$(REGSIZE) = sp;
MemDestCast(ptr,a0);
ptr = sp+4;
MemDestCast(ptr,a1);
}
REGSV_BLD3: REGSV_BLD2 is REGSV_BLD2 { build REGSV_BLD2; }
REGSV_BLD3: "a0-a2," is ext_value_b3=1 & ext_value_b2=1 & ext_value_b1=0 {
ptr:$(REGSIZE) = sp;
MemDestCast(ptr,a0);
ptr = sp+4;
MemDestCast(ptr,a1);
ptr = sp+8;
MemDestCast(ptr,a2);
}
REGSV_BLD4: REGSV_BLD3 is REGSV_BLD3 { build REGSV_BLD3; }
REGSV_BLD4: "a0-a3," is ext_value_areg=0b1110 {
ptr:$(REGSIZE) = sp;
MemDestCast(ptr,a0);
ptr = sp+4;
MemDestCast(ptr,a1);
ptr = sp+8;
MemDestCast(ptr,a2);
ptr = sp+12;
MemDestCast(ptr,a3);
}
SAVE_ARG: is ext_value_areg=0 | ext_value_areg=1 | ext_value_areg=2 | ext_value_areg=3 | ext_value_areg=0xb | ext_value_areg=0xf {}
SAVE_ARG: REGSV_BLD4 is REGSV_BLD4 {
build REGSV_BLD4;
}
REGRS_S0: is m16_svrs_s0 {}
REGRS_S0: is m16_svrs_s0=1 { tsp = tsp-$(REGSIZE); MemSrcCast(s0,tsp); }
REGRS_S1: is m16_svrs_s1 {}
REGRS_S1: is m16_svrs_s1=1 { tsp = tsp-$(REGSIZE); MemSrcCast(s1,tsp); }
REGRS_S8: is ext_value_xreg=6 {}
REGRS_S8: is ext_value_xreg { tsp = tsp-$(REGSIZE); MemSrcCast(s8,tsp); }
REGRS_S7: is ext_value_xreg=5 {}
REGRS_S7: is REGRS_S8 { build REGRS_S8; tsp = tsp-$(REGSIZE); MemSrcCast(s7,tsp); }
REGRS_S6: is ext_value_xreg=4 {}
REGRS_S6: is REGRS_S7 { build REGRS_S7; tsp = tsp-$(REGSIZE); MemSrcCast(s6,tsp); }
REGRS_S5: is ext_value_xreg=3 {}
REGRS_S5: is REGRS_S6 { build REGRS_S6; tsp = tsp-$(REGSIZE); MemSrcCast(s5,tsp); }
REGRS_S4: is ext_value_xreg=2 {}
REGRS_S4: is REGRS_S5 { build REGRS_S5; tsp = tsp-$(REGSIZE); MemSrcCast(s4,tsp); }
REGRS_S3: is ext_value_xreg=1 {}
REGRS_S3: is REGRS_S4 { build REGRS_S4; tsp = tsp-$(REGSIZE); MemSrcCast(s3,tsp); }
REGRS_S2: is ext_value_xreg=0 {}
REGRS_S2: is REGRS_S3 { build REGRS_S3; tsp = tsp-$(REGSIZE); MemSrcCast(s2,tsp); }
REST_SREG: is m16_svrs_s0=0 & m16_svrs_s1=0 & ext_value_xreg=0 {}
REST_SREG: ","ext_svrs_sreg is m16_svrs_s0 & m16_svrs_s1 & ext_value_xreg & ext_svrs_sreg & REGRS_S0 & REGRS_S1 & REGRS_S2
[ext_svrs_s0=m16_svrs_s0;ext_svrs_s1=m16_svrs_s1;ext_svrs_xs=ext_value_xreg;] {
build REGRS_S2;
build REGRS_S1;
build REGRS_S0;
}
REGSV_S0: is m16_svrs_s0 {}
REGSV_S0: is m16_svrs_s0=1 { tsp = tsp-$(REGSIZE); MemDestCast(tsp,s0);}
REGSV_S1: is m16_svrs_s1 {}
REGSV_S1: is m16_svrs_s1=1 { tsp = tsp-$(REGSIZE); MemDestCast(tsp,s1); }
REGSV_S8: is ext_value_xreg=6 {}
REGSV_S8: is ext_value_xreg { tsp = tsp-$(REGSIZE); MemDestCast(tsp,s8); }
REGSV_S7: is ext_value_xreg=5 {}
REGSV_S7: is REGSV_S8 { build REGSV_S8; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s7); }
REGSV_S6: is ext_value_xreg=4 {}
REGSV_S6: is REGSV_S7 { build REGSV_S7; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s6); }
REGSV_S5: is ext_value_xreg=3 {}
REGSV_S5: is REGSV_S6 { build REGSV_S6; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s5); }
REGSV_S4: is ext_value_xreg=2 {}
REGSV_S4: is REGSV_S5 { build REGSV_S5; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s4); }
REGSV_S3: is ext_value_xreg=1 {}
REGSV_S3: is REGSV_S4 { build REGSV_S4; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s3); }
REGSV_S2: is ext_value_xreg=0 {}
REGSV_S2: is REGSV_S3 { build REGSV_S3; tsp = tsp-$(REGSIZE); MemDestCast(tsp,s2); }
SAVE_SREG: is m16_svrs_s0=0 & m16_svrs_s1=0 & ext_value_xreg=0 {}
SAVE_SREG: ","ext_svrs_sreg is m16_svrs_s0 & m16_svrs_s1 & ext_value_xreg & ext_svrs_sreg & REGSV_S0 & REGSV_S1 & REGSV_S2
[ext_svrs_s0=m16_svrs_s0;ext_svrs_s1=m16_svrs_s1;ext_svrs_xs=ext_value_xreg;] {
build REGSV_S2;
build REGSV_S1;
build REGSV_S0;
}
REST_RA: is m16_svrs_ra=0 {}
REST_RA: ",ra" is m16_svrs_ra=1 {
tsp = tsp-$(REGSIZE);
MemSrcCast(ra,tsp);
}
SAVE_RA: is m16_svrs_ra=0 {}
SAVE_RA: ",ra" is m16_svrs_ra=1 {
tsp = tsp-$(REGSIZE);
MemDestCast(tsp,ra);
}
REST_TOP: EXT_FRAME^REST_RA^REST_SREG^REST_STAT is EXT_FRAME & REST_RA & REST_SREG & REST_STAT {
build EXT_FRAME;
tmp:2 = EXT_FRAME;
tsp = sp+zext(tmp);
build REST_RA;
build REST_SREG;
build REST_STAT;
sp = sp+zext(tmp);
}
SAVE_TOP: SAVE_ARG^EXT_FRAME^SAVE_RA^SAVE_SREG^SAVE_STAT is EXT_FRAME & SAVE_RA & SAVE_SREG & SAVE_ARG & SAVE_STAT {
tsp = sp;
build SAVE_ARG;
build SAVE_RA;
build SAVE_SREG;
build SAVE_STAT;
build EXT_FRAME;
tmp:2 = EXT_FRAME;
sp = sp - zext(tmp);
}
# The non-extended PC relative clears the lower 2 bits *after* the add.
# The extended version clears the lower 2 bits *before* the add. The difference in how they do it is correct
:addiu RX32, pc, EXT_IU8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00001 & ext_is_ext=0 & RX32 & EXT_IU8 & pc & ext_delay & RX {
tmp:4 = zext(EXT_IU8);
tmpa:4 = ext_delay;
RX32 = (inst_start + tmp - (tmpa << 1)) & 0xFFFFFFFC;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addiu RX32, pc, EXT_IS8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00001 & ext_is_ext=1 & RX32 & EXT_IS8 & pc & RX {
tmp:4 = sext(EXT_IS8);
RX32 = (inst_start & 0xFFFFFFFC) + tmp;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addiu RX32, EXT_IS8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01001 & RX32 & EXT_IS8 & RX {
tmp:4 = sext(EXT_IS8);
RX32 = RX32 + tmp;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addiu RY32, RX32, EXT_RRIA is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01000 & m16_rria_f=0 & RX32 & RY32 & EXT_RRIA & RX {
tmp:4 = sext(EXT_RRIA);
RY32 = RX32 + tmp;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addiu sp, EXT_IS8L3 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b011 & ext_is_ext=0 & sp & EXT_IS8L3 {
tmp:$(REGSIZE) = sext(EXT_IS8L3);
sp = sp + tmp;
}
:addiu sp, EXT_IS8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b011 & ext_is_ext=1 & sp & EXT_IS8 {
tmp:$(REGSIZE) = sext(EXT_IS8);
sp = sp + tmp;
}
:addiu RX32, sp, EXT_IU8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00000 & ext_is_ext=0 & sp & RX32 & EXT_IU8 & RX {
tmp:4 = zext(EXT_IU8);
RX32 = sp:4 + tmp;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addiu RX32, sp, EXT_IS8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00000 & ext_is_ext=1 & sp & RX32 & EXT_IS8 & RX {
tmp:4 = sext(EXT_IS8);
RX32 = sp:4 + tmp;
@ifdef MIPS64
RX = sext(RX32);
@endif
}
:addu RZ32, RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & ext_is_ext=0 & m16_op=0b11100 & m16_rrr_f=0b01 & RX32 & RY32 & RZ32 & RZ {
RZ32 = RX32 + RY32;
@ifdef MIPS64
RZ = sext(RZ32);
@endif
}
:and m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01100 & m16_rx & m16_ry {
m16_rx = m16_rx & m16_ry;
}
:asmacro ext_value_select is ISA_MODE=1 & RELP=1 & ext_isjal=0 & ext_is_ext=1 & m16_op=0b11100 & ext_value_select {
}
:b Rel16_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00010 & Rel16_m16 {
goto Rel16_m16;
}
:beqz RX32, CRel16_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00100 & RX32 & CRel16_m16 {
if (RX32 == 0) goto CRel16_m16;
}
:bnez RX32, CRel16_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00101 & RX32 & CRel16_m16 {
if (RX32 != 0) goto CRel16_m16;
}
:break m16_code is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00101 & m16_code {
tmp:4=m16_code;
trap(tmp);
}
:bteqz CRel16_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b000 & CRel16_m16 {
if (t8 == 0) goto CRel16_m16;
}
:btnez CRel16_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b001 & CRel16_m16 {
if (t8 != 0) goto CRel16_m16;
}
:cmp m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01010 & m16_rx & m16_ry {
t8 = m16_rx ^ m16_ry;
}
:cmpi m16_rx, m16_iu8_imm is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01110 & ext_is_ext=0 & m16_rx & m16_iu8_imm {
tmpa:1 = m16_iu8_imm;
tmp:$(REGSIZE) = zext(tmpa);
t8 = m16_rx ^ tmp;
}
:cmpi m16_rx, EXT_RI is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01110 & ext_is_ext=1 & m16_rx & EXT_RI {
tmp:$(REGSIZE) = zext(EXT_RI);
t8 = m16_rx ^ tmp;
}
:div RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b11010 & RX32 & RY32 {
if (RY32 == 0) goto <done>;
lo = sext(RX32 s/ RY32);
hi = sext(RX32 s% RY32);
<done>
}
:divu RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b11011 & RX32 & RY32 {
if (RY32 == 0) goto <done>;
lo = sext(RX32 / RY32);
hi = sext(RX32 % RY32);
<done>
}
:jal Abs26_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=1 & ext_tgt_x=0 & Abs26_m16 [ ext_delay=0b10; globalset(inst_next, ext_delay);] {
ra = inst_next | 0x1;
delayslot( 1 );
call Abs26_m16;
#double check gpr31 bit
}
:jalr m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=0 & m16_rr_l=1 & m16_rr_ra=0 & m16_rr_f=0b00000 & m16_rx [globalset(inst_next, ext_delay);] {
JXWritePC(m16_rx);
ra = inst_next | 0x1;
delayslot( 1 );
call [pc];
}
:jalrc m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=1 & m16_rr_l=1 & m16_rr_ra=0 & m16_rr_f=0b00000 & m16_rx {
JXWritePC(m16_rx);
ra = inst_next | 0x1;
call [pc];
}
:jalx Abs26_m16 is ISA_MODE=1 & RELP=1 & ext_isjal=1 & ext_tgt_x=1 & Abs26_m16 [ ISA_MODE = 0; globalset(Abs26_m16, ISA_MODE);
globalset(inst_next, ext_delay); ] {
ra = inst_next | 0x1;
delayslot( 1 );
ISAModeSwitch = 0;
call Abs26_m16;
}
:jr ra is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=0 & m16_rr_l=0 & m16_rr_ra=1 & ra & m16_rr_f=0b00000 & m16_rx=0 [globalset(inst_next, ext_delay);] {
JXWritePC(ra);
delayslot( 1 );
return [pc];
}
:jr m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=0 & m16_rr_l=0 & m16_rr_ra=0 & m16_rr_f=0b00000 & m16_rx [globalset(inst_next, ext_delay);] {
JXWritePC(m16_rx);
delayslot( 1 );
goto [pc];
}
:jrc ra is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=1 & m16_rr_l=0 & m16_rr_ra=1 & ra & m16_rr_f=0b00000 & m16_rx=0 {
JXWritePC(ra);
return [pc];
}
:jrc m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_nd=1 & m16_rr_l=0 & m16_rr_ra=0 & m16_rr_f=0b00000 & m16_rx {
JXWritePC(m16_rx);
goto [pc];
}
:lb m16_ry, OFF_M16S0 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10000 & m16_ry & OFF_M16S0 {
m16_ry = sext(*[ram]:1 OFF_M16S0);
}
:lbu m16_ry, OFF_M16S0 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10100 & m16_ry & OFF_M16S0 {
m16_ry = zext(*[ram]:1 OFF_M16S0);
}
:lh m16_ry, OFF_M16S1 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10001 & m16_ry & OFF_M16S1 {
m16_ry = sext(*[ram]:2 OFF_M16S1);
}
:lhu m16_ry, OFF_M16S1 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10101 & m16_ry & OFF_M16S1 {
m16_ry = zext(*[ram]:2 OFF_M16S1);
}
:li m16_rx, EXT_LIU8 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01101 & m16_rx & EXT_LIU8 {
m16_rx = zext(EXT_LIU8);
}
:lw m16_ry, OFF_M16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10011 & m16_ry & OFF_M16 {
m16_ry = sext(*[ram]:4 OFF_M16);
}
:lw m16_rx, OFF_M16PC is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10110 & m16_rx & OFF_M16PC & ext_delay {
m16_rx = sext(*[ram]:4 OFF_M16PC);
}
:lw m16_rx, OFF_M16SP is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b10010 & m16_rx & OFF_M16SP {
m16_rx = sext(*[ram]:4 OFF_M16SP);
}
:mfhi m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b10000 & m16_rr_z=0 & m16_rx {
m16_rx = hi;
}
:mflo m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b10010 & m16_rr_z=0 & m16_rx {
m16_rx = lo;
}
:move ext_m16r32, m16_mv_rz is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b101 & ext_m16r32 & m16_mv_rz & m16_i8_r32_20 & m16_i8_r32_43 [ ext_reg_low = m16_i8_r32_20; ext_reg_high = m16_i8_r32_43 ; ] {
ext_m16r32 = m16_mv_rz;
}
:move m16_ry, m16_i8_r32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b111 & m16_ry & m16_i8_r32 {
m16_ry = m16_i8_r32;
}
:mult RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b11000 & RX32 & RY32 {
tmp1:8 = sext( RX32 );
tmp2:8 = sext( RY32 );
prod:8 = tmp1 * tmp2;
lo = sext(prod:4);
prod = prod >> 32;
hi = sext(prod:4);
}
:multu RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b11001 & RX32 & RY32 {
tmp1:8 = zext( RX32 );
tmp2:8 = zext( RY32 );
prod:8 = tmp1 * tmp2;
lo = sext(prod:4);
prod = prod >> 32;
hi = sext(prod:4);
}
:neg RX, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01011 & RX & RY32 {
RX = sext(0-RY32);
}
:not m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01111 & m16_rx & m16_ry {
m16_rx = ~m16_ry;
}
# nop is technically a special case of a move instruction that moves 0 to 0
:nop is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b101 & m16_i8_imm=0 & m16_ri_z=0 {}
:or m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01101 & m16_rx & m16_ry {
m16_rx = m16_rx | m16_ry;
}
# save/restore argument format
#<a0-a3 saved as arguments (save only)>,<framesize>,<ra>,<s0-s8>,<a0-a3 saved as static>
:restore REST_TOP is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b100 & m16_svrs_s=0 & REST_TOP {
build REST_TOP;
}
:save SAVE_TOP is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_f=0b100 & m16_svrs_s=1 & SAVE_TOP {
build SAVE_TOP;
}
:sb RY32, OFF_M16S0 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11000 & RY32 & OFF_M16S0 {
*[ram]:1 OFF_M16S0 = RY32:1;
}
:sdbbp m16_code is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00001 & m16_code {
signalDebugBreakpointException();
}
:seb m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b10001 & m16_rr_z=0b100 & m16_rx {
tmp:1 = m16_rx:1;
tmpb:$(REGSIZE) = sext(tmp);
m16_rx = tmpb;
}
:seh m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b10001 & m16_rr_z=0b101 & m16_rx {
tmp:2 = m16_rx:2;
tmpb:$(REGSIZE) = sext(tmp);
m16_rx = tmpb;
}
:sh m16_ry, OFF_M16S1 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11001 & m16_ry & OFF_M16S1 {
*[ram]:2 OFF_M16S1 = m16_ry:2;
}
:sll m16_rx, m16_ry, EXT_SHIFT is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00110 & m16_shft_f=0b00 & m16_rx & m16_ry & EXT_SHIFT {
m16_rx = m16_ry << EXT_SHIFT;
}
:sllv m16_ry, m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00100 & m16_rx & m16_ry {
m16_ry = m16_ry << (m16_rx & 0x1f);
}
:slt m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00010 & m16_rx & m16_ry {
t8 = zext( m16_rx s< m16_ry );
}
:slti m16_rx, EXT_SET is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01010 & m16_rx & EXT_SET {
tmpa:4 = EXT_SET;
tmp:$(REGSIZE) = sext(tmpa);
t8 = zext( m16_rx s< tmp);
}
:sltiu m16_rx, EXT_SET is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01011 & m16_rx & EXT_SET {
tmpa:4 = EXT_SET;
tmp:$(REGSIZE) = sext(tmpa);
t8 = zext( m16_rx < tmp);
}
:sltu m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00011 & m16_rx & m16_ry {
t8 = zext( m16_rx < m16_ry );
}
:sra m16_rx, m16_ry, EXT_SHIFT is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00110 & m16_shft_f=0b11 & m16_rx & m16_ry & EXT_SHIFT {
m16_rx = m16_ry s>> EXT_SHIFT;
}
:srav m16_ry, m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00111 & m16_rx & m16_ry {
m16_ry = m16_ry s>> (m16_rx & 0x1f);
}
:srl m16_rx, m16_ry, EXT_SHIFT is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b00110 & m16_shft_f=0b10 & m16_rx & m16_ry & EXT_SHIFT {
m16_rx = m16_ry >> EXT_SHIFT;
}
:srlv m16_ry, m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b00110 & m16_rx & m16_ry {
m16_ry = m16_ry >> (m16_rx & 0x1f);
}
:subu RZ32, RX32, RY32 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & ext_is_ext=0 & m16_op=0b11100 & m16_rrr_f=0b11 & RX32 & RY32 & RZ32 & RZ {
RZ32 = RX32 - RY32;
@ifdef MIPS64
RZ = sext(RZ32);
@endif
}
:sw m16_ry, OFF_M16 is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11011 & m16_ry & OFF_M16 {
*[ram]:4 OFF_M16 = m16_ry:4;
}
:sw m16_rx, OFF_M16SP is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11010 & m16_rx & OFF_M16SP {
*[ram]:4 OFF_M16SP = m16_rx:4;
}
:sw ra, OFF_M16SP is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b01100 & m16_i8_sw=0b010 & ra & OFF_M16SP {
*[ram]:4 OFF_M16SP = ra:4;
}
:xor m16_rx, m16_ry is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_f=0b01110 & m16_rx & m16_ry {
m16_rx = m16_rx ^ m16_ry;
}
:zeb m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_z=0b000 & m16_rr_f=0b10001 & m16_rx {
tmp:1 = m16_rx:1;
m16_rx = zext(tmp);
}
:zeh m16_rx is ISA_MODE=1 & RELP=1 & ext_isjal=0 & m16_op=0b11101 & m16_rr_z=0b001 & m16_rr_f=0b10001 & m16_rx {
tmp:2 = m16_rx:2;
m16_rx = zext(tmp);
}