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

889 lines
32 KiB
Plaintext
Executable File

# MIPS Common specification file for 32 and 64-bit processors
# Appropriate defines (MIPS32, MIPS64, MIPS64_32ADDRS) must be
# specified before including this file
# The following Coprocessor configuration is supported:
# COP0: integrated CPU virtual memory and exception handler
# COP1: Floating-point Unit (FPU)
# COP2: <not supported>
# COP3: Used for MIPS64 FPU extended instructions (see COP1X)
#
# ################################
#
# Notes for the elf header e_flags "secondary" field in the MIPS.opinion file.
#
# "-" indicates don't care
#
# 0x5------- MIPS32 Release 1, 32-bit addresses, ABI is o32, FREGSIZE = 4, gcc -mips32
# Example: 0x50001001, secondary="1342181377"
#
# 0x6-----2- MIPS64 Release 1, 32-bit addresses, ABI is n32, FREGSIZE = 8, gcc -mips64
#
# 0x6-----0- MIPS64 Release 1, 64-bit addresses, ABI is n64, FREGSIZE = 8, gcc -mips64 -mabi-64
#
# 0x7------- MIPS32 Release 2, ABI is o32, gcc -mips32r2 to r5
# if 0x00000200 is set then FREGSIZE = 8 else FREGSIZE = 4
# 0x70001001, secondary="1879052289"
# with mips16: 0x74001001
#
# 0x8-----2- MIPS64 Release 2, 32-bit addresses, ABI is n32, FREGSIZE = 8, gcc -mips64r2 to r5
# 0x80000021, secondary="2147483681"
#
# 0x8-----0- MIPS64 Release 2, 64-bit addresses, ABI is n64, gcc -mips64r2 to r5 -mabi-64
# 0x80000001
#
# 0x9------- MIPS32 Release 6, ABI is o32, gcc -mips32r6
# if 0x00000200 is set then FREGSIZE = 8 else FREGSIZE = 4
#
# 0xa-----2- MIPS64 Release 6, 32-bit addresses, ABI is n32, FREGSIZE = 8, gcc -mips64r6
# 0xa0000421
#
# 0xa-----0- MIPS64 Release 6, 64-bit addresses, ABI is n64, FREGSIZE = 8, gcc -mips64r6 -mabi-64
#
# Masks:
#
# 0x04000000 MIPS-16
#
# 0x02000000 MicroMIPS
#
# ################################
#
# Notes about register names and function args:
#
# Function args are passed in a0 - a3, which are the same as $4 - $7, other args are on the stack
# Floating point args are in f12 and f14
#
# Function return values are stored in v0 (and v1 if the regs are 32-bit and return type is 64-bits)
# v0 and v1 are the same as general purpose regs $2 and $3
# Floating point return values are in f0 (and f1 if needed for binding)
#
# $29 is the stack pointer sp
# $30 is the frame pointer fp also called s8
# $31 is the return address ra
#
# ################################
# There is now support for single and double floating point instructions, with the following limitations:
#
# The PS paired single fmt1 format is not implemented. In paired single instructions,
# the specified 64-bit floating point register operands are each considered as two separate
# 32-bit floating points numbers, and they are processed in parallel with the same instuction.
# (This is supposed to be the first microprocessor implementation of SIMD.)
#
# Only COP1 Floating point coprocessor unit 1 is supported (there is no support for unit 2)
#
# Some notes about MIPS Floating Point, derived from the FPU table on page 87 of the MIPS
# Architecture Volume 1, 2014
#
# FPU configuration is stored in a 32-bit read-only Floating Point Implementation Register (FIR),
# this is also known as CP1 Control Register 0.
# Bit 22, called F64 or also called the FR bit, is = 1 when you have 64-bit FPRs,
# else if the FR bit = 0 then you have 32-bit FPRs
#
# The macro FREGSIZE = 4 for 32-bit FPRs, and = 8 for 64-bit FPRs
#
# Other info is in the FCSR register, CP1 Register 31.
# Bit 23 is one condition code, and bits 25-31 is the FCC with other condition codes,
# which are set after a compare. Note this FCRE register is removed in Release 6.
#
# MIPS32 Release 1:
# The FPU (floating point unit) has 32 32-bit FPRs
# 64-bit floating point doubles are stored in even-odd pairs of FPRs
# F64 = 0
#
# MIPS32 Release 2 and later:
# FPU has 32 64-bit FPRs
# F64 = 1
# Use these gcc options to get 64-bit floating point instructions: -mips32r2 -mfp64
# (gcc default is 32-bit FPRs)
#
# MIPS64 Release 1 - 5
# The FPU has 32 64-bit FPRs
# F64 = 1
#
# MIPS32 Release 6:
# In "strictly 32-bit" mode there are 32 32-bit FPRs, and bonding of two 32-bit FPRs to support
# 64-bit floating point is not allowed
# F64 = 0
#
# MIPS64 Release 6:
# FPU has 32 64-bit FPRs, when F64 = 1
# In "strictly 32-bit" mode there are 32 32-bit FPRs, and bonding of two 32-bit FPRs is not allowed
# F64 = 0
#
# Release 6:
# Floating point condition codes are removed, and replaced by a new CMP.condn.fmt instruction
# The PS paired-single format in floating point instructions is removed - this was when
# two 32-bit floats were stuffed into one 64-bit FPR, and supported SIMD.
#
# In function calls, floating point args are passed in FPRs f12 to f15, and the return value is in f0
#
# When you have 32-bit FPRs, then 64-bit double floats are created by bonding a pair of 32-bit FPRs.
# f0 is the low half or has the LSB or also called lower word of the double, and
# f1 is the high half or has the MSB or also called upper word of the double
#
# When you have a 64-bit longword integer:
# For function return longword values:
# $2 (same as v0) holds the MSB top half of the longword
# $3 (same as v1) holds the LSB bottom half of the longword
#
# Note that when FREGSIZE = 8 (ie, 64-bit FPRs) and you have a single 32-bit float, then the
# 32-bit float data is stored in bits 0-31 of the FPR. (Bits 32-63 are "unused".)
#
# Note that when conversions are done to/from floats, doubles, ints, and longs (64-bit) that rounding
# errors can occur in the simulator, so equality comparisons should be done carefully.
#
# ################################
#
#-----
@ifdef MIPS64
@ifdef MIPS64_32ADDRS # used for 64-bit mips restricted to 32-bit addresses
@define REGSIZE "8" # General purpose register size (8 or 4)
@define FREGSIZE "8" # Floating point register size (8 or 4)
@define ADDRSIZE "4" # Memory address size (8 or 4, virtual and physical)
@define SIZETO4 "4" # In 32-bit mode, no truncation needed
@define ADDRCAST ":4" # need to down cast to pointer size
@define NEEDCAST "1"
@else # full 64 bit ptrs
@define REGSIZE "8" # General purpose register size (8 or 4)
@define FREGSIZE "8" # Floating point register size (8 or 4)
@define ADDRSIZE "8" # Memory address size (8 or 4, virtual and physical)
@define SIZETO4 "4" # In 64-bit mode, use when need to do 32-bit operation
@define ADDRCAST "" # no need to down cast to pointer size
@endif #MIPS64_32ADDRS
@else # MIPS32
@define REGSIZE "4" # General purpose register size (8 or 4)
# FREGSIZE for mips32 is set in slaspec file
@define ADDRSIZE "4" # Memory address size (8 or 4, virtual and physical)
@define SIZETO4 "4"
@define ADDRCAST "" # no need to down cast to pointer size
@endif
#-----
define endian=$(ENDIAN);
define alignment=2;
define space ram type=ram_space size=$(ADDRSIZE) default;
define space register type=register_space size=4;
# General purpose registers
define register offset=0 size=$(REGSIZE) [
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
pc
];
@ifdef MIPS64
# We need the 32-bit pieces of the main registers for the 32-bit instructions
@if ENDIAN == "big"
define register offset=0 size=4 [
zero_hi zero_lo at_hi at_lo v0_hi v0_lo v1_hi v1_lo
a0_hi a0_lo a1_hi a1_lo a2_hi a2_lo a3_hi a3_lo
t0_hi t0_lo t1_hi t1_lo t2_hi t2_lo t3_hi t3_lo
t4_hi t4_lo t5_hi t5_lo t6_hi t6_lo t7_hi t7_lo
s0_hi s0_lo s1_hi s1_lo s2_hi s2_lo s3_hi s3_lo
s4_hi s4_lo s5_hi s5_lo s6_hi s6_lo s7_hi s7_lo
t8_hi t8_lo t9_hi t9_lo k0_hi k0_lo k1_hi k1_lo
gp_hi gp_lo sp_hi sp_lo s8_hi s8_lo ra_hi ra_lo
pc_hi pc_lo
];
@else
define register offset=0 size=4 [
zero_lo zero_hi at_lo at_hi v0_lo v0_hi v1_lo v1_hi
a0_lo a0_hi a1_lo a1_hi a2_lo a2_hi a3_lo a3_hi
t0_lo t0_hi t1_lo t1_hi t2_lo t2_hi t3_lo t3_hi
t4_lo t4_hi t5_lo t5_hi t6_lo t6_hi t7_lo t7_hi
s0_lo s0_hi s1_lo s1_hi s2_lo s2_hi s3_lo s3_hi
s4_lo s4_hi s5_lo s5_hi s6_lo s6_hi s7_lo s7_hi
t8_lo t8_hi t9_lo t9_hi k0_lo k0_hi k1_lo k1_hi
gp_lo gp_hi sp_lo sp_hi s8_lo s8_hi ra_lo ra_hi
pc_lo pc_hi
];
@endif # ENDIAN
@endif # MIPS64
# Floating point registers
@if FREGSIZE == "4"
# For 64-bit Double floating point operands need to bond two 32-bit FPRs
define register offset=0x1000 size=4 [
f1 f0 f3 f2 f5 f4 f7 f6
f9 f8 f11 f10 f13 f12 f15 f14
f17 f16 f19 f18 f21 f20 f23 f22
f25 f24 f27 f26 f29 f28 f31 f30
];
# Note ftD, fsD, and fdD and frD have been added to support 64-bit double floats
define register offset=0x1000 size=8 [
f0_1 f2_3 f4_5 f6_7
f8_9 f10_11 f12_13 f14_15
f16_17 f18_19 f20_21 f22_23
f24_25 f26_27 f28_29 f30_31
];
@else # FREGSIZE == "8"
define register offset=0x1000 size=8 [
f0 f1 f2 f3 f4 f5 f6 f7
f8 f9 f10 f11 f12 f13 f14 f15
f16 f17 f18 f19 f20 f21 f22 f23
f24 f25 f26 f27 f28 f29 f30 f31
];
@endif # FREGSIZE
# Floating point control registers (common to both MIPS32 and MIPS64)
define register offset=0x1200 size=4 [
fir fccr fexr fenr fcsr
];
# COP-0 control registers, sel=0
define register offset=0x2000 size=$(REGSIZE) [
Index Random EntryLo0 EntryLo1
Context PageMask Wired HWREna
BadVAddr Count EntryHi Compare
Status Cause EPC PRId
Config LLAddr WatchLo WatchHi
XContext cop0_reg21 cop0_reg22 Debug
DEPC PerfCnt ErrCtl CacheErr
TagLo TagHi ErrorEPC DESAVE
];
# COP-0 control registers, sel=1
define register offset=0x2100 size=$(REGSIZE) [
MVPControl VPEControl TCStatus cop0_reg3.1
ContextConfig PageGrain SRSConf0 cop0_reg7.1
cop0_reg8.1 cop0_reg9.1 cop0_reg10.1 cop0_reg11.1
IntCtl cop0_reg13.1 cop0_reg14.1 EBase
Config1 cop0_reg17.1 WatchLo.1 WatchHi.1
cop0_reg20.1 cop0_reg21.1 cop0_reg22.1 TraceControl
cop0_reg24.1 PerfCnt.1 cop0_reg26.1 CacheErr.1
DataLo.1 DataHi.1 cop0_reg30.1 cop0_reg31.1
];
# COP-0 control registers, sel=2
define register offset=0x2200 size=$(REGSIZE) [
MVPConf0 VPEConf0 TCBind cop0_reg3.2
cop0_reg4.2 cop0_reg5.2 SRSConf1 cop0_reg7.2
cop0_reg8.2 cop0_reg9.2 cop0_reg10.2 cop0_reg11.2
SRSCtl cop0_reg13.2 cop0_reg14.2 cop0_reg15.2
Config2 cop0_reg17.2 WatchLo.2 WatchHi.2
cop0_reg20.2 cop0_reg21.2 cop0_reg22.2 TraceControl2
cop0_reg24.2 PerfCnt.2 cop0_reg26.2 CacheErr.2
TagLo.2 TagHi.2 cop0_reg30.2 cop0_reg31.2
];
# COP-0 control registers, sel=3
define register offset=0x2300 size=$(REGSIZE) [
MVPConf1 VPEConf1 TCRestart cop0_reg3.3
cop0_reg4.3 cop0_reg5.3 SRSConf2 cop0_reg7.3
cop0_reg8.3 cop0_reg9.3 cop0_reg10.3 cop0_reg11.3
SRSMap cop0_reg13.3 cop0_reg14.3 cop0_reg15.3
Config3 cop0_reg17.3 WatchLo.3 WatchHi.3
cop0_reg20.3 cop0_reg21.3 cop0_reg22.3 UserTraceData
cop0_reg24.3 PerfCnt.3 cop0_reg26.3 CacheErr.3
DataLo.3 DataHi.3 cop0_reg30.3 cop0_reg31.3
];
# COP-0 control registers, sel=4
define register offset=0x2400 size=$(REGSIZE) [
cop0_reg0.4 YQMask TCHalt cop0_reg3.4
cop0_reg4.4 cop0_reg5.4 SRSConf3 cop0_reg7.4
cop0_reg8.4 cop0_reg9.4 cop0_reg10.4 cop0_reg11.4
cop0_reg12.4 cop0_reg13.4 cop0_reg14.4 cop0_reg15.4
cop0_reg16.4 cop0_reg17.4 WatchLo.4 WatchHi.4
cop0_reg20.4 cop0_reg21.4 cop0_reg22.4 TraceBPC
cop0_reg24.4 PerfCnt.4 cop0_reg26.4 CacheErr.4
TagLo.4 TagHi.4 cop0_reg30.4 cop0_reg31.4
];
# COP-0 control registers, sel=5
define register offset=0x2500 size=$(REGSIZE) [
cop0_reg0.5 VPESchedule TCContext cop0_reg3.5
cop0_reg4.5 cop0_reg5.5 SRSConf4 cop0_reg7.5
cop0_reg8.5 cop0_reg9.5 cop0_reg10.5 cop0_reg11.5
cop0_reg12.5 cop0_reg13.5 cop0_reg14.5 cop0_reg15.5
cop0_reg16.5 cop0_reg17.5 WatchLo.5 WatchHi.5
cop0_reg20.5 cop0_reg21.5 cop0_reg22.5 cop0_reg23.5
cop0_reg24.5 PerfCnt.5 cop0_reg26.5 CacheErr.5
DataLo.5 DataHi.5 cop0_reg30.5 cop0_reg31.5
];
# COP-0 control registers, sel=6
define register offset=0x2600 size=$(REGSIZE) [
cop0_reg0.6 VPEScheFBack TCSchedule cop0_reg3.6
cop0_reg4.6 cop0_reg5.6 cop0_reg6.6 cop0_reg7.6
cop0_reg8.6 cop0_reg9.6 cop0_reg10.6 cop0_reg11.6
cop0_reg12.6 cop0_reg13.6 cop0_reg14.6 cop0_reg15.6
cop0_reg16.6 cop0_reg17.6 WatchLo.6 WatchHi.6
cop0_reg20.6 cop0_reg21.6 cop0_reg22.6 cop0_reg23.6
cop0_reg24.6 PerfCnt.6 cop0_reg26.6 CacheErr.6
TagLo.6 TagHi.6 cop0_reg30.6 cop0_reg31.6
];
# COP-0 control registers, sel=7
define register offset=0x2700 size=$(REGSIZE) [
cop0_reg0.7 VPEOpt TCScheFBack cop0_reg3.7
cop0_reg4.7 cop0_reg5.7 cop0_reg6.7 cop0_reg7.7
cop0_reg8.7 cop0_reg9.7 cop0_reg10.7 cop0_reg11.7
cop0_reg12.7 cop0_reg13.7 cop0_reg14.7 cop0_reg15.7
cop0_reg16.7 cop0_reg17.7 WatchLo.7 WatchHi.7
cop0_reg20.7 cop0_reg21.7 cop0_reg22.7 cop0_reg23.7
cop0_reg24.7 PerfCnt.7 cop0_reg26.7 CacheErr.7
DataLo.7 DataHi.7 cop0_reg30.7 cop0_reg31.7
];
# Some other internal registers
define register offset=0x3000 size=$(REGSIZE) [ hi lo hi1 lo1 hi2 lo2 hi3 lo3 tsp ];
define register offset=0x3F00 size=1 [ ISAModeSwitch ];
# Define context bits
define register offset=0x4000 size=4 contextreg;
define context contextreg
PAIR_INSTRUCTION_FLAG=(0,0) noflow # =1 paired instruction
REL6=(31,31) # =1 Release 6, =0 Pre release 6, (Fixed, set via pspec)
RELP=(30,30) # =1 Mips16e, =0 MicroMips. REL6, RELP can't both be 1 (Fixed, set via pspec)
@ifdef ISA_VARIANT
ISA_MODE=(1,1) # =1 Decode using alternate ISA, variable.
LowBitCodeMode = (1,1) # =1 if low bit of instruction address is set on a branch
#below here is for mips16e. Overlaps with micromips
ext_isjal=(2,2) noflow
ext_value=(3,13) noflow
ext_value_select=(3,5) noflow
ext_value_1005=(3,8) noflow
ext_value_1004=(3,9) noflow
ext_value_sa40=(3,7) noflow
ext_value_xreg=(3,5) noflow
ext_value_frame=(6,9) noflow
ext_value_areg=(10,13) noflow
ext_value_b0=(13,13) noflow
ext_value_b1=(12,12) noflow
ext_value_b2=(11,11) noflow
ext_value_b3=(10,10) noflow
ext_value_saz=(8,13) noflow
ext_value_1511=(9,13) noflow
ext_value_1511s=(9,13) signed noflow
ext_value_1411=(10,13) noflow
ext_value_1411s=(10,13) signed noflow
ext_tgt_2521=(3,7) noflow
ext_tgt_2016=(8,12) noflow
ext_tgt_x=(13,13) noflow
ext_is_ext=(14,14) noflow
ext_m16r32=(15,19) noflow
ext_m16r32a=(15,19) noflow
ext_reg_high=(15,16) noflow
ext_reg_low=(17,19) noflow
ext_svrs_sreg=(20,24) noflow
ext_svrs_xs=(20,22) noflow
ext_svrs_s1=(23,23) noflow
ext_svrs_s0=(24,24) noflow
ext_done=(25,25) noflow
ext_delay=(26,27) noflow
#below here is for micromips. Overlaps with mips16e
ext_t4_name=(2,5) noflow
ext_t4=(2,5) noflow
ext_tra=(6,6) noflow
ext_32_code=(7,16) noflow
ext_32_codes=(7,16) signed noflow
ext_32_addim=(10,16) noflow
ext_32_addims=(10,16) signed noflow
ext_32_imm2=(15,16) noflow
ext_32_imm2s=(15,16) signed noflow
ext_32_imm3=(14,16) noflow
ext_32_imm3s=(14,16) signed noflow
ext_32_imm5=(12,16) noflow
ext_32_imm5s=(12,16) signed noflow
ext_32_imm6=(11,16) noflow
ext_32_rlist=(7,11) noflow
ext_32_base=(12,16) noflow
ext_32_basea=(12,16) noflow
ext_32_rd=(7,11) noflow
ext_32_rdset=(7,11) noflow
ext_32_rs1=(7,11) noflow
ext_32_rs1lo=(7,11) noflow
ext_32_rs1set=(7,11) noflow
ext_16_rs=(7,9) noflow
ext_16_rslo=(7,8) noflow
ext_16_rshi=(9,9) noflow
ext_off16_s=(7,22) signed noflow
ext_off16_u=(7,22) noflow
@endif # ISA_VARIANT
;
# Instruction fields
define token instr(32)
prime = (26,31)
bit25 = (25,25)
zero2325 = (23,25)
zero1 = (22,25)
rs32 = (21,25)
frD = (21,25)
rs = (21,25)
fr = (21,25)
base = (21,25)
format = (21,25)
copop = (21,25)
mfmc0 = (21,25)
zero21 = (21,25)
jsub = (21,25)
acflo = (21,22)
acfhi = (21,22)
breakcode = (6,25)
off26 = (0,25) signed # 26 bit signed offset, e.g. balc, bc
ind26 = (0,25) # 26 bit unsigned index, e.g. jal
copfill = (6,24)
cofun = (0,24)
off21 = (0,20) signed # 21 bit signed offset in conditional branch/link
off16 = (0,15) signed # 16 bit signed offset in conditional branch/link
bit21 = (21,21)
bitz19 = (19,20)
pcrel = (19,20)
pcrel2 = (18,20)
cc = (18,20)
rt32 = (16,20)
rt = (16,20)
ftD = (16,20)
ft = (16,20)
index = (16,20)
hint = (16,20)
cop1code = (16,20)
synci = (16,20)
cond = (16,20)
op = (16,20)
zero1620 = (16,20)
nd = (17,17)
tf = (16,16)
zero1320 = (13,20)
zero1315 = (13,15)
szero = (11,25)
baser6 = (11,15)
rd32 = (11,15)
rd = (11,15)
rd0_0 = (11,15)
rd0_1 = (11,15)
rd0_2 = (11,15)
rd0_3 = (11,15)
rd0_4 = (11,15)
rd0_5 = (11,15)
rd0_6 = (11,15)
rd0_7 = (11,15)
cp2cprSel0 = (11,15)
cp2cprSel1 = (11,15)
cp2cprSel2 = (11,15)
cp2cprSel3 = (11,15)
cp2cprSel4 = (11,15)
cp2cprSel5 = (11,15)
cp2cprSel6 = (11,15)
cp2cprSel7 = (11,15)
fsD = (11,15)
fs = (11,15)
fs_unk = (11,15)
fs_fcr = (11,15)
zero4 = (11,15)
msbd = (11,15)
aclo = (11,12)
achi = (11,12)
code = (6,15)
bit10 = (10,10)
spec2 = (9,10)
spec3 = (8,10)
simmed9 = (7,15)
zero2 = (7,10)
fdD = (6,10)
fd = (6,10)
stype = (6,10)
sa = (6,10)
lsb = (6,10)
fct2 = (6,10)
zero5 = (6,10)
wsbh = (6,10)
bp3 = (6,8)
sa2 = (6,7)
bp2 = (6,7)
zero6 = (3,10)
bigfunct = (0,10)
fct = (0,5)
bshfl = (0,5)
bit6 = (6,6)
zero3 = (0,4)
bit5 = (5,5)
op4 = (3,5)
sel = (0,2)
format1X = (0,2)
simmed19 = (0,18) signed
simmed18 = (0,17) signed
immed = (0,15)
simmed = (0,15) signed
simmseq = (6,15) signed
simmed11 = (0,10)
;
attach variables [ rs rt rd base index baser6 ] [
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 [ rs32 rt32 rd32 ] [
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
];
@else
# For MIPS32 these are the same as rs, rt, and rd
attach variables [ rs32 rt32 rd32 ] [
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
];
@endif
attach variables [ fs ft fd fr ] [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31
];
@if FREGSIZE == "4"
# For 64-bit floating point Double instruction operands need to bond two 32-bit FPRs
attach variables [ fsD ftD fdD frD ] [
f0_1 _ f2_3 _ f4_5 _ f6_7 _
f8_9 _ f10_11 _ f12_13 _ f14_15 _
f16_17 _ f18_19 _ f20_21 _ f22_23 _
f24_25 _ f26_27 _ f28_29 _ f30_31 _
];
@else # FREGSIZE == "8"
attach variables [ fsD ftD fdD frD ] [
f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15
f16 f17 f18 f19 f20 f21 f22 f23 f24 f25 f26 f27 f28 f29 f30 f31
];
@endif
# Only a few Floating Point Control (FCR) registers are defined
attach variables [ fs_fcr ] [
fir _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ _ _ _ _ _ _ _
_ fccr fexr _ fenr _ _ fcsr
];
attach variables [ rd0_0 ] [
Index Random EntryLo0 EntryLo1
Context PageMask Wired HWREna
BadVAddr Count EntryHi Compare
Status Cause EPC PRId
Config LLAddr WatchLo WatchHi
XContext cop0_reg21 cop0_reg22 Debug
DEPC PerfCnt ErrCtl CacheErr
TagLo TagHi ErrorEPC DESAVE
];
attach variables [ rd0_1 ] [
MVPControl VPEControl TCStatus cop0_reg3.1
ContextConfig PageGrain SRSConf0 cop0_reg7.1
cop0_reg8.1 cop0_reg9.1 cop0_reg10.1 cop0_reg11.1
IntCtl cop0_reg13.1 cop0_reg14.1 EBase
Config1 cop0_reg17.1 WatchLo.1 WatchHi.1
cop0_reg20.1 cop0_reg21.1 cop0_reg22.1 TraceControl
cop0_reg24.1 PerfCnt.1 cop0_reg26.1 CacheErr.1
DataLo.1 DataHi.1 cop0_reg30.1 cop0_reg31.1
];
attach variables [ rd0_2 ] [
MVPConf0 VPEConf0 TCBind cop0_reg3.2
cop0_reg4.2 cop0_reg5.2 SRSConf1 cop0_reg7.2
cop0_reg8.2 cop0_reg9.2 cop0_reg10.2 cop0_reg11.2
SRSCtl cop0_reg13.2 cop0_reg14.2 cop0_reg15.2
Config2 cop0_reg17.2 WatchLo.2 WatchHi.2
cop0_reg20.2 cop0_reg21.2 cop0_reg22.2 TraceControl2
cop0_reg24.2 PerfCnt.2 cop0_reg26.2 CacheErr.2
TagLo.2 TagHi.2 cop0_reg30.2 cop0_reg31.2
];
attach variables [ rd0_3 ] [
MVPConf1 VPEConf1 TCRestart cop0_reg3.3
cop0_reg4.3 cop0_reg5.3 SRSConf2 cop0_reg7.3
cop0_reg8.3 cop0_reg9.3 cop0_reg10.3 cop0_reg11.3
SRSMap cop0_reg13.3 cop0_reg14.3 cop0_reg15.3
Config3 cop0_reg17.3 WatchLo.3 WatchHi.3
cop0_reg20.3 cop0_reg21.3 cop0_reg22.3 UserTraceData
cop0_reg24.3 PerfCnt.3 cop0_reg26.3 CacheErr.3
DataLo.3 DataHi.3 cop0_reg30.3 cop0_reg31.3
];
attach variables [ rd0_4 ] [
cop0_reg0.4 YQMask TCHalt cop0_reg3.4
cop0_reg4.4 cop0_reg5.4 SRSConf3 cop0_reg7.4
cop0_reg8.4 cop0_reg9.4 cop0_reg10.4 cop0_reg11.4
cop0_reg12.4 cop0_reg13.4 cop0_reg14.4 cop0_reg15.4
cop0_reg16.4 cop0_reg17.4 WatchLo.4 WatchHi.4
cop0_reg20.4 cop0_reg21.4 cop0_reg22.4 TraceBPC
cop0_reg24.4 PerfCnt.4 cop0_reg26.4 CacheErr.4
TagLo.4 TagHi.4 cop0_reg30.4 cop0_reg31.4
];
attach variables [ rd0_5 ] [
cop0_reg0.5 VPESchedule TCContext cop0_reg3.5
cop0_reg4.5 cop0_reg5.5 SRSConf4 cop0_reg7.5
cop0_reg8.5 cop0_reg9.5 cop0_reg10.5 cop0_reg11.5
cop0_reg12.5 cop0_reg13.5 cop0_reg14.5 cop0_reg15.5
cop0_reg16.5 cop0_reg17.5 WatchLo.5 WatchHi.5
cop0_reg20.5 cop0_reg21.5 cop0_reg22.5 cop0_reg23.5
cop0_reg24.5 PerfCnt.5 cop0_reg26.5 CacheErr.5
DataLo.5 DataHi.5 cop0_reg30.5 cop0_reg31.5
];
attach variables [ rd0_6 ] [
cop0_reg0.6 VPEScheFBack TCSchedule cop0_reg3.6
cop0_reg4.6 cop0_reg5.6 cop0_reg6.6 cop0_reg7.6
cop0_reg8.6 cop0_reg9.6 cop0_reg10.6 cop0_reg11.6
cop0_reg12.6 cop0_reg13.6 cop0_reg14.6 cop0_reg15.6
cop0_reg16.6 cop0_reg17.6 WatchLo.6 WatchHi.6
cop0_reg20.6 cop0_reg21.6 cop0_reg22.6 cop0_reg23.6
cop0_reg24.6 PerfCnt.6 cop0_reg26.6 CacheErr.6
TagLo.6 TagHi.6 cop0_reg30.6 cop0_reg31.6
];
attach variables [ rd0_7 ] [
cop0_reg0.7 VPEOpt TCScheFBack cop0_reg3.7
cop0_reg4.7 cop0_reg5.7 cop0_reg6.7 cop0_reg7.7
cop0_reg8.7 cop0_reg9.7 cop0_reg10.7 cop0_reg11.7
cop0_reg12.7 cop0_reg13.7 cop0_reg14.7 cop0_reg15.7
cop0_reg16.7 cop0_reg17.7 WatchLo.7 WatchHi.7
cop0_reg20.7 cop0_reg21.7 cop0_reg22.7 cop0_reg23.7
cop0_reg24.7 PerfCnt.7 cop0_reg26.7 CacheErr.7
DataLo.7 DataHi.7 cop0_reg30.7 cop0_reg31.7
];
attach variables [ aclo acflo ] [ lo lo1 lo2 lo3 ];
attach variables [ achi acfhi ] [ hi hi1 hi2 hi3 ];
attach names hint [
"load" "store" "hint2" "hint3" "load_streamed" "store_streamed" "load_retained" "store_retained"
"hint8" "hint9" "hint10" "hint11" "hint12" "hint13" "hint14" "hint15"
"hint16" "hint17" "hint18" "hint19" "hint20" "hint21" "hint22" "hint23" "hint24"
"writeback_invalidate" "hint26" "hint27" "hint28" "hint29" "PrepareForStore" "hint31" ];
# Subconstructors
RD0: rd0_0 is rd0_0 & sel=0 { export rd0_0; }
RD0: rd0_1 is rd0_1 & sel=1 { export rd0_1; }
RD0: rd0_2 is rd0_2 & sel=2 { export rd0_2; }
RD0: rd0_3 is rd0_3 & sel=3 { export rd0_3; }
RD0: rd0_4 is rd0_4 & sel=4 { export rd0_4; }
RD0: rd0_5 is rd0_5 & sel=5 { export rd0_5; }
RD0: rd0_6 is rd0_6 & sel=6 { export rd0_6; }
RD0: rd0_7 is rd0_7 & sel=7 { export rd0_7; }
RD: rd is rd { export rd; }
RDsrc: rd is rd { export rd; }
RDsrc: rd is rd & rd=0 { export 0:$(REGSIZE); }
RS: rs is rs { export rs; }
RSsrc: rs is rs { export rs; }
RSsrc: rs is rs & rs=0 { export 0:$(REGSIZE); }
RT: rt is rt { export rt; }
RTsrc: rt is rt { export rt; }
RTsrc: rt is rt & rt=0 { export 0:$(REGSIZE); }
RD32: rd is rd & rd32 { export rd32; }
RS32src: rs is rs & rs32 { export rs32; }
RS32src: rs is rs & rs32=0 { export 0:4; }
RT32: rt is rt & rt32 { export rt32; }
RT32src: rt is rt & rt32 { export rt32; }
RT32src: rt is rt & rt32=0 { export 0:4; }
@ifdef NEEDCAST
macro MemSrcCast(dest,src) {
dest = *(src:$(ADDRSIZE));
}
macro MemDestCast(dest,src) {
*(dest:$(ADDRSIZE)) = src;
}
macro ValCast(dest,src) {
dest = src:$(ADDRSIZE);
}
@else
macro MemSrcCast(dest,src) {
dest = *(src);
}
macro MemDestCast(dest,src) {
*(dest) = src;
}
macro ValCast(dest,src) {
dest = src;
}
@endif
OFF_BASE: simmed(base) is simmed & base { tmp:$(REGSIZE) = base + simmed; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
INDEX_BASE: index(base) is index & base { tmp:$(REGSIZE) = base + index; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_BASER6: simmed(base) is REL6=0 & simmed & base { tmp:$(REGSIZE) = base + simmed; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
OFF_BASER6: simmed9(base) is REL6=1 & simmed9 & base { tmp:$(REGSIZE) = base + simmed9; tmpscaled:$(ADDRSIZE) = 0; ValCast(tmpscaled,tmp); export tmpscaled; }
S18L3: val is simmed18 [ val = simmed18 << 3; ] { export *[const]:4 val; }
S19L2: val is simmed19 [ val = simmed19 << 2; ] { export *[const]:4 val; }
S16L16: val is simmed [ val = simmed << 16; ] { export *[const]:4 val; }
S16L32: val is simmed [ val = simmed << 32; ] { export *[const]:8 val; }
S16L48: val is simmed [ val = simmed << 48; ] { export *[const]:8 val; }
SAV: val is sa2 [ val = sa2+1; ] { export *[const]:1 val; }
Rel16: reloc is off16 [ reloc=inst_start+4+4*off16; ] { export *:$(ADDRSIZE) reloc; }
Rel21: reloc is off21 [ reloc=inst_start+4+4*off21; ] { export *:$(ADDRSIZE) reloc; }
Rel26: reloc is off26 [ reloc=inst_start+4+4*off26; ] { export *:$(ADDRSIZE) reloc; }
Abs26: reloc is ind26 [ reloc=((inst_start+4) $and 0xfffffffff0000000) | 4*ind26; ] { export *:$(ADDRSIZE) reloc; }
InsSize: mysize is msbd & lsb [ mysize = msbd - lsb + 1; ] { tmp:1 = mysize; export tmp; }
ExtSize: mysize is msbd [ mysize = msbd + 1; ] { tmp:1 = mysize; export tmp; }
@ifdef MIPS64
DextmSize: mysize is msbd [ mysize = msbd + 1 + 32; ] { tmp:1 = mysize; export tmp; }
DXuPos: pos is lsb [ pos = lsb + 32; ] { tmp:1 = pos; export tmp; }
DinsXSize: mysize is msbd & lsb [ mysize = msbd - lsb + 1 + 32; ] { tmp:1 = mysize; export tmp; }
@endif
macro JXWritePC(addr) {
ISAModeSwitch = (addr & 0x1) != 0;
tmp:$(REGSIZE) = -2;
tmp = tmp & addr;
pc = tmp;
}
# Floating point formats
#fmt: "S" is format=0x10 { }
#fmt: "D" is format=0x11 { }
#fmt: "W" is format=0x14 { }
#fmt: "L" is format=0x15 { }
#fmt: "PS" is format=0x16 { }
fmt1: "S" is format=0x10 { }
fmt1: "D" is format=0x11 { }
fmt1: "PS" is format=0x16 { }
fmt2: "S" is format=0x10 { }
fmt2: "D" is format=0x11 { }
fmt3: "S" is format=0x10 { }
fmt3: "W" is format=0x14 { }
fmt3: "L" is format=0x15 { }
fmt4: "D" is format=0x11 { }
fmt4: "W" is format=0x14 { }
fmt4: "L" is format=0x15 { }
fmt5: "S" is format1X=0x0 { }
fmt5: "D" is format1X=0x1 { }
fmt5: "PS" is format1X=0x6 { }
# Release 6 and later:
fmt6: "S" is format=0x14 { }
fmt6: "D" is format=0x15 { }
# Custom Pcode Operations
#
# To add a new pcodeop op that is implemented in Java code:
#
# In this directory:
# ./ghidra/Ghidra/Processors/MIPS/src/main/java/ghidra/program/emulation
# Edit this file to register a new Java method that implements the pcodeop:
# MIPSEmulateInstructionStateModifier.java
# (Be sure to also import the new class)
#
# The mips.pspec file must have this key set (this has already been done):
# <property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.MIPSEmulateInstructionStateModifier"/>
#
# Add the Java class file for the new pcodeop here:
# ./ghidra/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/pcode/emulate/callother
#
define pcodeop break;
define pcodeop trap;
define pcodeop wait;
define pcodeop syscall;
define pcodeop cacheOp;
define pcodeop signalDebugBreakpointException;
define pcodeop disableInterrupts;
define pcodeop enableInterrupts;
define pcodeop hazzard;
define pcodeop lockload;
define pcodeop lockwrite;
define pcodeop synch;
define pcodeop tlbop;
define pcodeop bitSwap;
define pcodeop disableProcessor;
define pcodeop enableProcessor;
define pcodeop signalReservedInstruction;
define pcodeop TLB_invalidate;
define pcodeop TLB_invalidate_flush;
define pcodeop TLB_probe_for_matching_entry;
define pcodeop TLB_read_indexed_entryHi;
define pcodeop TLB_read_indexed_entryLo0;
define pcodeop TLB_read_indexed_entryLo1;
define pcodeop TLB_read_indexed_entryPageMask;
define pcodeop TLB_write_indexed_entry;
define pcodeop TLB_write_random_entry;
# prefetch(vaddr, hint);
define pcodeop prefetch;
# getFpCondition(cc)
define pcodeop getFpCondition;
# getCopCondition(cop_num, cc)
define pcodeop getCopCondition;
# setCopControlWord(cop_num, reg_num, value)
define pcodeop setCopControlWord;
# getCopControlWord(cop_num, reg_num)
define pcodeop getCopControlWord;
# copFunction(cop_num, func)
define pcodeop copFunction;
# getCopReg(cop_num, reg_num)
define pcodeop getCopReg;
define pcodeop getCopRegH;
# setCopReg(cop_num, reg_num, value)
define pcodeop setCopReg;
define pcodeop setCopRegH;
# countLeadingOnes(val)
define pcodeop countLeadingOnes;
# countLeadingZeros(val)
define pcodeop countLeadingZeros;
# extractField(value, msbd, lsb)
define pcodeop extractField;
# getHWRegister(regnum)
define pcodeop getHWRegister;
# setShadow(sgpr, value)
define pcodeop setShadow;
# gpr = getShadow(sgpr)
define pcodeop getShadow;