889 lines
32 KiB
Plaintext
Executable File
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;
|