1747 lines
77 KiB
Plaintext
1747 lines
77 KiB
Plaintext
# PA-RISC common specification file for 32 and 64-bit processors
|
|
# Appropriate defines (PARISC32, PARISC64) must be
|
|
# specified before including this file
|
|
|
|
# Known Issues:
|
|
# The branch target is annotated onto the line following the branch, not the branch itself
|
|
# There may still be issues with condition codes and instructions like INST,=,N r2,r3,r2 that write back into one of the input argument registers.
|
|
# The condition uses the final value in r2, when it should use the value passed in to r2 before the operation.
|
|
# The implementation of space registers is incorrect. There should really be a 64 bit address space with space register in the upper 64 bits.
|
|
# Right now, the space register is either ignored or else just added to the base address.
|
|
# Some of the pcode could be simplified.
|
|
|
|
|
|
# Attention- Sometimes the source and destination registers can be the same registers.
|
|
# When you write to a destination reg, it's important that your pcode always keeps a temp copy
|
|
# of the original if you later refer to a source reg.
|
|
|
|
|
|
# Register conventions
|
|
#
|
|
# r0 is always 0
|
|
# r1 scratch register, caller saved
|
|
# r2 is rp is the return pointer
|
|
# r3 to r18 callee saves
|
|
# r19 to r22 caller saves
|
|
# r23 is arg3
|
|
# r24 is arg2
|
|
# r25 is arg1
|
|
# r26 is arg0
|
|
# r27 is the global data pointer dp and must be set to the .data symbol in the elf header
|
|
# r28 is ret0 the subroutine return value, high order word if a 64-bit return value
|
|
# r29 is ret1 the low order word of a 64-bit return value
|
|
# r30 is sp the stack pointer
|
|
# r31 is the millicode return pointer
|
|
#
|
|
# fr0 is farg0 if floating arg is 32-bits, 64-bit args are in farg1 high and low
|
|
# fr1 is farg0 if floating arg is 32-bits
|
|
# fr2 is farg0 if floating arg is 32-bits, 64-bit args are in farg3 high and low
|
|
# fr0 is farg0 if floating arg is 32-bits
|
|
# fr4 is fret floating point return (8 bytes)
|
|
#
|
|
# Note- only two double arguments can be passed in registers.
|
|
# If a function return value is larger than 64 bits, then the caller passes the address in r28
|
|
#
|
|
# Note- function calls and returns are usually through relocation stubs
|
|
#
|
|
|
|
#-----
|
|
@ifdef PARISC64
|
|
@define REGSIZE "8" # General purpose register size (8 or 4)
|
|
@define ADDRSIZE "8" # Memory address size (8 bytes in 64 bit mode)
|
|
|
|
@else # PARISC32
|
|
@define REGSIZE "4" # General purpose register size (8 or 4)
|
|
@define ADDRSIZE "4" # Memory address size (8 bytes, using the space registers as the upper 32 bits and the regular base and offset as the lower 32 bits)
|
|
@endif
|
|
#-----
|
|
|
|
define endian=$(ENDIAN);
|
|
|
|
define alignment=4;
|
|
|
|
# I'm not sure what to set for the sizes of these spaces -- TODO set these correctly
|
|
define space ram type=ram_space size=$(ADDRSIZE) default;
|
|
define space register type=register_space size=4; # this is a large enough address space to address all the registers. Two bytes would probably be enough
|
|
|
|
# General purpose registers
|
|
define register offset=0 size=$(REGSIZE) [
|
|
r0 r1 rp r3
|
|
r4 r5 r6 r7
|
|
r8 r9 r10 r11
|
|
r12 r13 r14 r15
|
|
r16 r17 r18 r19
|
|
r20 r21 r22 r23
|
|
r24 r25 r26 dp
|
|
r28 r29 sp r31
|
|
];
|
|
|
|
# Floating point registers
|
|
define register offset=0x1000 size=8 [
|
|
fr0 fpe23 fpe45 fpe67 fr4 fr5 fr6 fr7
|
|
fr8 fr9 fr10 fr11 fr12 fr13 fr14 fr15
|
|
fr16 fr17 fr18 fr19 fr20 fr21 fr22 fr23
|
|
fr24 fr25 fr26 fr27 fr28 fr29 fr30 fr31
|
|
];
|
|
|
|
define register offset=0x1000 size=4 [
|
|
fr0R fr0L fpe2 fpe3 fpe4 fpe5 fpe6 fpe7
|
|
fr4L fr4R fr5L fr5R fr6L fr6R fr7L fr7R
|
|
fr8L fr8R fr9L fr9R fr10L fr10R
|
|
fr11L fr11R fr12L fr12R fr13L fr13R fr14L fr14R
|
|
fr15L fr15R fr16L fr16R fr17L fr17R fr18L fr18R
|
|
fr19L fr19R fr20L fr20R fr21L fr21R fr22L fr22R
|
|
fr23L fr23R fr24L fr24R fr25L fr25R fr26L fr26R
|
|
fr27L fr27R fr28L fr28R fr29L fr29R fr30L fr30R
|
|
fr31L fr31R
|
|
];
|
|
|
|
# Floating Point Status Register
|
|
# Only the compare bit and the compare queue are implemented here
|
|
# and the Condition Queue is only 8 bits, rather than 10
|
|
define register offset=0x1100 size=1 [
|
|
compareBit compareQueue
|
|
];
|
|
|
|
# Shadow Registers
|
|
define register offset=0x2000 size=$(REGSIZE) [
|
|
shr0 shr1 shr2 shr3 shr4 shr5 shr6
|
|
];
|
|
|
|
# Space Registers
|
|
define register offset=0x3000 size=4 [
|
|
sr0 sr1 sr2 sr3 sr4 sr5 sr6 sr7
|
|
];
|
|
|
|
# Processor Status Word
|
|
define register offset=0x4000 size=1 [
|
|
pswY pswZ pswE pswS pswT pswH pswL pswN pswX pswB pswC pswV pswM pswCB pswG pswF pswR pswQ pswP pswD pswI
|
|
];
|
|
|
|
# Control Registers
|
|
define register offset=0x5000 size=4 [
|
|
cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7
|
|
cr8 cr9 cr10 sar cr12 cr13 cr14 cr15
|
|
cr16 cr17 cr18 cr19 cr20 cr21 cr22 cr23
|
|
cr24 cr25 cr26 cr27 cr28 cr29 cr30 cr31
|
|
];
|
|
|
|
# instruction address offset and instruction address space queues
|
|
# these are used for branching, to compute target addresses and deal with branch delay slots
|
|
define register offset=0x6000 size=4 [
|
|
iasq_front iasq_back iaoq_front iaoq_back
|
|
];
|
|
|
|
# special hidden registers to support the nullify and delay slot features of PA-RISC
|
|
define register offset=0x7000 size=1 [nullifyCond nullifyNextCond branchCond branchExecuted];
|
|
define register offset=0x7100 size=4 [branchIndDest nullifyCondResult];
|
|
|
|
define register offset=0x7200 size=12 contextreg;
|
|
define context contextreg
|
|
|
|
# transient context
|
|
phase = (0,2) noflow
|
|
temp1 = (3,3)
|
|
|
|
# stored context
|
|
nullifyEnable = (4,4) noflow
|
|
branchCouldBeNullified = (5,5) noflow
|
|
branchEnable = (6,6) noflow
|
|
branchType = (7,9) noflow
|
|
# These do not appear to be used:
|
|
# branchIsInd = (7,7) noflow
|
|
# branchIsCond = (8,8) noflow
|
|
# branchIsCall = (9,9) noflow
|
|
branchIsReturn = (10,10) noflow # used for returns
|
|
padding = (10,31) noflow
|
|
branchImmDest = (32,63) noflow
|
|
temp32 = (64,95) noflow
|
|
;
|
|
|
|
@define COMMON "phase=1 "
|
|
|
|
# Instruction fields
|
|
|
|
define token instr(32)
|
|
opfam = (26,31)
|
|
cr = (21,25)
|
|
crname2 = (21,25)
|
|
freg2 = (21,25)
|
|
freg2sgl = (21,25)
|
|
fr2half = (21,25)
|
|
fusedr2 = (21,25)
|
|
reg2 = (21,25)
|
|
b = (21,25)
|
|
bboffset = (21,25)
|
|
crname1 = (21,25)
|
|
bit20 = (20,20) signed
|
|
fpc1sub2 = (17,20)
|
|
highIm10 = (16,25)
|
|
reg1 = (16,20)
|
|
fusedr1 = (16,20)
|
|
freg1 = (16,20)
|
|
freg1sgl = (16,20)
|
|
fr1half = (16,20)
|
|
r = (16,20)
|
|
highIm5 = (16,20) signed
|
|
highIm5less16 = (17,20)
|
|
tr = (16,20)
|
|
x = (16,20)
|
|
w1 = (16,20)
|
|
bit16 = (16,16)
|
|
fpc1sub = (15,16)
|
|
srbit1 = (15,15)
|
|
s = (14,15)
|
|
srbit0 = (14,14)
|
|
im13 = (13,25) signed
|
|
SEDCondSym = (13,15)
|
|
RegUnitCondSym = (13,15)
|
|
InvUnitCondSym = (13,15)
|
|
RegLogicCondSym = (13,15)
|
|
InvLogicCondSym = (13,15)
|
|
RegAddCondSym = (13,15)
|
|
InvAddCondSym = (13,15)
|
|
RegCSCondSym = (13,15)
|
|
InvCSCondSym = (13,15)
|
|
c = (13,15)
|
|
fpsub = (13,15)
|
|
srbit2 = (13,13)
|
|
fpdf = (13,14)
|
|
fixeddf = (13,14)
|
|
fpdfraw = (13,14)
|
|
fixedsf = (13,14)
|
|
a = (13,13)
|
|
u = (13,13)
|
|
fpr1x = (12,12)
|
|
f = (12,12)
|
|
fv = (12,12)
|
|
zero = (12,12)
|
|
one = (12,12)
|
|
subop1012 = (10,12)
|
|
im15 = (11,25)
|
|
sopim10 = (11,20) signed
|
|
sopim5 = (11,15) signed
|
|
fpta = (11,15)
|
|
fusedta = (11,15)
|
|
fpsf = (11,12)
|
|
fpsfraw = (11,12)
|
|
fpfmt = (11,12)
|
|
fpfmt1bit = (11,11)
|
|
bit11 = (11,11)
|
|
cc = (10,11)
|
|
ldcc = (10,11)
|
|
stcc = (10,11)
|
|
ldcwcc = (10,11)
|
|
bit10 = (10,10)
|
|
sopim17 = (9,25)
|
|
pmuop = (9,13)
|
|
specop = (9,10)
|
|
fpclass = (9,10)
|
|
bit9 = (9,9)
|
|
bit8 = (8,8)
|
|
fpx = (8,8)
|
|
bits78 = (7,8)
|
|
fpr2x = (7,7)
|
|
fpra = (6,10)
|
|
fusedra = (6,10)
|
|
ext4 = (6,9)
|
|
C = (6,9)
|
|
subop = (6,9)
|
|
sysopshifted= (6,13)
|
|
sysopshiftedshort = (6,12)
|
|
op = (6,11)
|
|
sfu = (6,8)
|
|
fp0czero = (6,8)
|
|
fptx = (6,6)
|
|
bit6 = (6,6)
|
|
sysop = (5,12)
|
|
i2 = (5,11)
|
|
bits59 = (5,9)
|
|
cp = (5,9)
|
|
fusedfmt = (5,5)
|
|
bit5 = (5,5)
|
|
m = (5,5)
|
|
spn = (5,5)
|
|
w2 = (2,12)
|
|
w2_2 = (2,2)
|
|
w2less2 = (3,12)
|
|
n = (1,1)
|
|
im26 = (0,25) signed
|
|
sim21 = (0,20) signed
|
|
sim14 = (0,13) signed
|
|
im21less0 = (1,20)
|
|
im21_1_12 = (1,11)
|
|
im21_12_14 = (12,13)
|
|
im21_14_16 = (14,15)
|
|
im21_16_21 = (16,20)
|
|
im14 = (0,13)
|
|
im14less0 = (1,13)
|
|
im11 = (0,10) signed
|
|
im11less0 = (1,11)
|
|
sim5 = (0,4) signed
|
|
im5 = (0,4)
|
|
im5less0 = (1,4)
|
|
fpcond = (0,4)
|
|
fptest = (0,4)
|
|
fpt = (0,4)
|
|
fptsgl = (0,4)
|
|
fusedrt = (0,4)
|
|
fpthalf = (0,4)
|
|
crnamet = (0,4)
|
|
t = (0,4)
|
|
bit0 = (0,0)
|
|
w = (0,0)
|
|
;
|
|
|
|
# general purpose registers
|
|
attach variables [reg1 reg2 t r b x] [
|
|
r0 r1 rp r3 r4 r5 r6 r7
|
|
r8 r9 r10 r11 r12 r13 r14 r15
|
|
r16 r17 r18 r19 r20 r21 r22 r23
|
|
r24 r25 r26 dp r28 r29 sp r31
|
|
];
|
|
|
|
# fp registers - 64 bit doubles
|
|
attach variables [ freg2 freg1 fpt fpra fpta ] [
|
|
fr0 fpe23 fpe45 fpe67 fr4 fr5 fr6 fr7
|
|
fr8 fr9 fr10 fr11 fr12 fr13 fr14 fr15
|
|
fr16 fr17 fr18 fr19 fr20 fr21 fr22 fr23
|
|
fr24 fr25 fr26 fr27 fr28 fr29 fr30 fr31
|
|
];
|
|
|
|
# 64 bit fp registers when used as 32 bit (.sgl completer)
|
|
# This mapping goes from bit pattern N -> register NL
|
|
attach variables [ freg2sgl freg1sgl fptsgl ] [
|
|
fr0L fpe2 fpe4 fpe6 fr4L fr5L fr6L fr7L
|
|
fr8L fr9L fr10L fr11L fr12L fr13L fr14L fr15L
|
|
fr16L fr17L fr18L fr19L fr20L fr21L fr22L fr23L
|
|
fr24L fr25L fr26L fr27L fr28L fr29L fr30L fr31L
|
|
];
|
|
|
|
# 32 bit single precision mode fpra fpta for mult-add and mult-sub instructions
|
|
attach variables [ fusedra fusedta fusedr2 fusedr1 fusedrt ] [
|
|
fr16L fr17L fr18L fr19L fr20L fr21L fr22L fr23L
|
|
fr24L fr25L fr26L fr27L fr28L fr29L fr30L fr31L
|
|
fr16R fr17R fr18R fr19R fr20R fr21R fr22R fr23R
|
|
fr24R fr25R fr26R fr27R fr28R fr29R fr30R fr31R
|
|
];
|
|
|
|
# control registers
|
|
attach variables [ cr ] [
|
|
cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7
|
|
cr8 cr9 cr10 sar cr12 cr13 cr14 cr15
|
|
cr16 cr17 cr18 cr19 cr20 cr21 cr22 cr23
|
|
cr24 cr25 cr26 cr27 cr28 cr29 cr30 cr31
|
|
];
|
|
|
|
# control registers by their purpose names
|
|
attach names [ crname2 crname1 crnamet ] [
|
|
RCTR CR1 CR2 CR3 CR4 CR5 CR6 CR7
|
|
PID1 PID2 CCR SAR PID3 PID4 IVA EIEM
|
|
ITMR IIASQ IIAOQ IIR ISR IOR IPSW EIRR
|
|
TMP0 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 TMP7
|
|
];
|
|
|
|
attach names [ ldcc ] [
|
|
none resv sl resv
|
|
];
|
|
|
|
attach names [ stcc ] [
|
|
none BC SL resv
|
|
];
|
|
|
|
attach names [ ldcwcc ] [
|
|
none CO resv resv
|
|
];
|
|
|
|
# Table 5-7
|
|
attach names [ SEDCondSym ] [
|
|
"" ",=" ",<" ",OD" ",TR" ",<>" ",>=" ",EV"
|
|
];
|
|
|
|
attach names [ RegUnitCondSym ] [
|
|
"" _ ",SBZ" ",SHZ" ",SDC" _ ",SBC" ",SHC"
|
|
];
|
|
|
|
attach names [ InvUnitCondSym ] [
|
|
"" _ ",NBZ" ",NHZ" ",NDC" _ ",NBC" ",NHC"
|
|
];
|
|
|
|
attach names [ RegLogicCondSym ] [
|
|
"" ",=" ",<" ",<=" _ _ _ ",OD"
|
|
];
|
|
|
|
attach names [ InvLogicCondSym ] [
|
|
"" ",<>" ",>=" ",>" _ _ _ ",EV"
|
|
];
|
|
|
|
# Table 5-4
|
|
attach names [ RegAddCondSym ] [
|
|
"" ",=" ",<" ",<=" ",NUV" ",ZNV" ",SV" ",OD"
|
|
];
|
|
|
|
attach names [ InvAddCondSym ] [
|
|
"" ",<>" ",>=" ",>" ",UV" ",VNZ" ",NSV" ",EV"
|
|
];
|
|
|
|
attach names [ RegCSCondSym ] [
|
|
"" ",=" ",<" ",<=" ",<<" ",<<=" ",SV" ",OD"
|
|
];
|
|
|
|
attach names [ InvCSCondSym ] [
|
|
"" ",<>" ",>=" ",>" ",>>=" ",>>" ",NSV" ",EV"
|
|
];
|
|
|
|
# the different tests used by the FTEST instruction
|
|
attach names [ fptest ] [
|
|
"" "ACC" "REJ" _ _ "ACC8" "REJ8" _ _ "ACC6" _ _ _ "ACC4" _ _ _ "ACC2" _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
];
|
|
|
|
# the floating point number types
|
|
attach names [ fpsf fpdf fpfmt ] [
|
|
",SGL" ",DBL" ",QUAD" _
|
|
];
|
|
|
|
attach names [ fpfmt1bit ] [
|
|
",SGL" ",DBL"
|
|
];
|
|
|
|
# the fixed point number types
|
|
attach names [ fixedsf fixeddf ] [
|
|
",UW" ",UD" ",UQ" _
|
|
];
|
|
|
|
# the floating point number types for fused ops
|
|
attach names [ fusedfmt ] [
|
|
",DBL" ",SGL"
|
|
];
|
|
|
|
|
|
######################################################################################
|
|
# caret instruction builders for nullify and branch
|
|
######################################################################################
|
|
# These all assume a fall through from a preceding branch
|
|
# If there is a branch into the delay slot of a different branch,
|
|
# then the branch logic will still be present from the preceding instruction
|
|
# and the control flow will branch to that destination.
|
|
# This case should result in a red bookmark due to the disassembly context difference
|
|
# These all also assume that the instruction following a branch (in the delay slot)
|
|
# does not nullify its succeeding instruction
|
|
#######################################################################################
|
|
# no branch, no nullify
|
|
# previous instruction was not a branch and did not nullify this instruction
|
|
:^instruction is phase=0 & branchEnable=0 & nullifyEnable=0 & instruction [ phase=1; ] {
|
|
nullifyNextCond=0;
|
|
build instruction;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# previous instruction was not a branch, but may have conditionally nullified this instruction
|
|
:^instruction is phase=0 & branchEnable=0 & nullifyEnable=1 & instruction [ phase=1; ] {
|
|
local wasNullified = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
if (wasNullified) goto <skip>;
|
|
build instruction;
|
|
nullifyCond=nullifyNextCond;
|
|
<skip>
|
|
}
|
|
|
|
#
|
|
# Handle branches that don't nullify their branch delay slot instructions
|
|
# These instructions themselves may have been nullified, so we need to
|
|
# check and conditionally execute the branch based on that.
|
|
#
|
|
# Need to reset branchCond = 0 before build instruction because the insruction does not reset it,
|
|
# and if branchcond is not reset, then it persists to subsequent instructions.
|
|
|
|
immediateDest: is branchImmDest { export *:$(ADDRSIZE) branchImmDest; }
|
|
|
|
# previous instruction was a branch, but this instruction was not nullified
|
|
# but branch instruction could have been nullified
|
|
# branchType = 0, unconditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=0 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( previousBranchExecuted ) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# previous instruction was a branch, but this instruction was not nullified
|
|
# branchType = 0, unconditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=0 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchCond = 0;
|
|
branchExecuted=0;
|
|
build instruction;
|
|
goto immediateDest;
|
|
}
|
|
|
|
# branchType = 1, unconditional immediate call
|
|
# this doesn't handle the case where the inst in the delay slot nullifies the next instruction
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=1 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! previousBranchExecuted ) goto <skip>;
|
|
call immediateDest;
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 1, unconditional immediate call
|
|
# this doesn't handle the case where the inst in the delay slot nullifies the next instruction
|
|
# this is the case where the branch could not have been nullified
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=1 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
call immediateDest;
|
|
}
|
|
|
|
# branchType = 2, conditional immediate branch
|
|
# the preceding instruction was a branch that may or may not have been taken and may or may not have been nullified
|
|
# but was not nullifying itself (the delay slot must execute)
|
|
# this doesn't handle the case where the instruction in the branch delay slot nullifies the next instruction
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=2 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
build instruction;
|
|
if (previousBranchCond && previousBranchExecuted) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 2, conditional immediate branch
|
|
# the preceding instruction was a branch that may or may not have been taken and may or may not have been nullified
|
|
# but was not nullifying itself (the delay slot must execute)
|
|
# this doesn't handle the case where the instruction in the branch delay slot nullifies the next instruction
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=2 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
build instruction;
|
|
if (previousBranchCond) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;}
|
|
|
|
# branchType = 3, conditional immediate call, (currently not used, may not exist in PA-RISC)
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=3 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! (previousBranchCond && previousBranchExecuted) ) goto <skip>;
|
|
call immediateDest;
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 3, conditional immediate call, (currently not used, may not exist in PA-RISC)
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=3 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
nullifyNextCond=0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! (previousBranchCond) ) goto <skip>;
|
|
call immediateDest;
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 4, unconditional indirect branch
|
|
# the preceding instruction was a branch that did not nullify its branch delay slot inst
|
|
# The branch is indirect and may have been nullified
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchCouldBeNullified=1 & branchType=4 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! previousBranchExecuted ) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 4, unconditional indirect branch and also return
|
|
# the preceding instruction was a branch that did not nullify its branch delay slot inst
|
|
# The branch is indirect and WAS NOT nullified
|
|
#
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchCouldBeNullified=0 & branchType=4 & instruction & branchIsReturn=0 [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
goto [branchIndDest];
|
|
}
|
|
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchCouldBeNullified=0 & branchType=4 & instruction & branchIsReturn=1 [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
return [branchIndDest];
|
|
}
|
|
|
|
|
|
# branchType = 5, unconditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=5 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! previousBranchExecuted ) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 5, unconditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=5 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
call [branchIndDest];
|
|
}
|
|
|
|
# branchType = 6, conditional indirect branch
|
|
# previous instruction was a conditional branch that may or may not be taken and may have been nullified
|
|
# however, the branch does not nullify the inst in its branch delay slot
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=6 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! previousBranchExecuted || ! previousBranchCond) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 6, conditional indirect branch
|
|
# previous instruction was a conditional branch that may or may not be taken and may have been nullified
|
|
# however, the branch does not nullify the inst in its branch delay slot
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=6 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
build instruction;
|
|
if ( ! previousBranchCond ) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 7, conditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=7 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
build instruction;
|
|
if ( ! previousBranchExecuted || ! previousBranchCond) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 7, conditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=0 & branchType=7 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond= branchCond;
|
|
branchCond = 0;
|
|
build instruction;
|
|
if ( ! previousBranchCond) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
#
|
|
# Handle branches with nullification -- the branch may nullify its branch delay slot
|
|
#
|
|
|
|
# branchType = 0, unconditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=0 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
if ( previousBranchExecuted ) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 0, unconditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=0 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
goto immediateDest;
|
|
}
|
|
|
|
# branchType = 1, unconditional immediate call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=1 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
if ( ! previousBranchExecuted ) goto <nobranch>;
|
|
call immediateDest;
|
|
<nobranch>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 1, unconditional immediate call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=1 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
call immediateDest;
|
|
}
|
|
|
|
# branchType = 2, conditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=2 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
if (previousBranchCond && previousBranchExecuted) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 2, conditional immediate branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=2 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0; # Need to reset branchCond
|
|
if (nullify) goto <skip>;
|
|
build instruction;
|
|
<skip>
|
|
if (previousBranchCond) goto immediateDest;
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 3, conditional immediate call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=3 & branchCouldBeNullified=1 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! (previousBranchCond && previousBranchExecuted) ) goto <nobranch>;
|
|
call immediateDest;
|
|
<nobranch>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 3, conditional immediate call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=3 & branchCouldBeNullified=0 & instruction & immediateDest [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyNextCond=0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchCond ) goto <nobranch>;
|
|
call immediateDest;
|
|
<nobranch>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 4, unconditional indirect branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=4 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchExecuted ) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 4, unconditional indirect branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=4 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
goto [branchIndDest];
|
|
}
|
|
|
|
# branchType = 5, unconditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=5 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchExecuted ) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 5, unconditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=5 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond = 0;
|
|
branchExecuted = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
call [branchIndDest];
|
|
}
|
|
|
|
# branchType = 6, conditional indirect branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=6 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchExecuted || ! previousBranchCond) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 6, conditional indirect branch
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=6 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyCond = 0;
|
|
nullifyNextCond=0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchCond) goto <skip>;
|
|
goto [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 7, conditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=7 & branchCouldBeNullified=1 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyNextCond=0;
|
|
local previousBranchExecuted = branchExecuted;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchExecuted || ! previousBranchCond) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
# branchType = 7, conditional indirect call
|
|
:^instruction is phase=0 & branchEnable=1 & nullifyEnable=1 & branchType=7 & branchCouldBeNullified=0 & instruction [ phase=1; ] {
|
|
local nullify = nullifyCond;
|
|
nullifyNextCond=0;
|
|
branchExecuted = 0;
|
|
local previousBranchCond = branchCond;
|
|
branchCond = 0;
|
|
if (nullify) goto <wasnullified>;
|
|
build instruction;
|
|
<wasnullified>
|
|
if ( ! previousBranchCond ) goto <skip>;
|
|
call [branchIndDest];
|
|
<skip>
|
|
nullifyCond=nullifyNextCond;
|
|
}
|
|
|
|
############################################################
|
|
# Subconstructors
|
|
############################################################
|
|
|
|
#############################
|
|
# general purpose registers selected
|
|
# by different fields for different purposes (index, base, general, src, target, ...)
|
|
#############################
|
|
R1: reg1 is reg1 & reg1=0 { export 0:$(REGSIZE); }
|
|
R1: reg1 is reg1 { export reg1; }
|
|
R1dst: reg1 is reg1 { export reg1; }
|
|
|
|
R2: reg2 is reg2 & reg2=0 { export 0:$(REGSIZE); }
|
|
R2: reg2 is reg2 { export reg2; }
|
|
R2dst: reg2 is reg2 { export reg2; }
|
|
|
|
RT: t is t { export t; }
|
|
|
|
RB: b is b & b=0 { export 0:$(REGSIZE); }
|
|
RB: b is b { export b; }
|
|
|
|
RX: is x=0 { export 0:$(REGSIZE); }
|
|
RX: x is x { export x; }
|
|
|
|
RR: r is r & r=0 { export 0:$(REGSIZE); }
|
|
RR: r is r { export r; }
|
|
|
|
SAR: "SAR" is epsilon { export sar; }
|
|
SR0: sr0 is sr0 { export sr0; }
|
|
R31: r31 is r31 { export r31; }
|
|
|
|
# 64 bit fp register access
|
|
FPR164: freg1 is freg1 { export freg1; }
|
|
FPR264: freg2 is freg2 { export freg2; }
|
|
FPRT64: fpt is fpt { export fpt; }
|
|
|
|
# register encoding for fused ops (fmpyadd, fmpysub)
|
|
FUSEDR1: fusedr1 is fusedr1 { export fusedr1; }
|
|
FUSEDR2: fusedr2 is fusedr2 { export fusedr2; }
|
|
FUSEDRA: fusedra is fusedra { export fusedra; }
|
|
FUSEDTA: fusedta is fusedta { export fusedta; }
|
|
FUSEDRT: fusedrt is fusedrt { export fusedrt; }
|
|
|
|
# 32 bit fp register access, lower half (L) and upper half (R)
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 0 { export fr0L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 1 { export fpe2; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 2 { export fpe4; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 3 { export fpe6; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 4 { export fr4L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 5 { export fr5L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 6 { export fr6L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 7 { export fr7L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 8 { export fr8L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 9 { export fr9L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 10 { export fr10L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 11 { export fr11L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 12 { export fr12L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 13 { export fr13L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 14 { export fr14L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 15 { export fr15L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 16 { export fr16L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 17 { export fr17L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 18 { export fr18L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 19 { export fr19L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 20 { export fr20L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 21 { export fr21L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 22 { export fr22L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 23 { export fr23L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 24 { export fr24L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 25 { export fr25L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 26 { export fr26L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 27 { export fr27L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 28 { export fr28L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 29 { export fr29L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 30 { export fr30L; }
|
|
FPR132: freg1^"L" is fpr1x = 0 & freg1 & fr1half = 31 { export fr31L; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 0 { export fr0R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 1 { export fpe3; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 2 { export fpe5; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 3 { export fpe7; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 4 { export fr4R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 5 { export fr5R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 6 { export fr6R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 7 { export fr7R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 8 { export fr8R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 9 { export fr9R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 10 { export fr10R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 11 { export fr11R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 12 { export fr12R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 13 { export fr13R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 14 { export fr14R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 15 { export fr15R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 16 { export fr16R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 17 { export fr17R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 18 { export fr18R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 19 { export fr19R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 20 { export fr20R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 21 { export fr21R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 22 { export fr22R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 23 { export fr23R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 24 { export fr24R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 25 { export fr25R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 26 { export fr26R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 27 { export fr27R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 28 { export fr28R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 29 { export fr29R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 30 { export fr30R; }
|
|
FPR132: freg1^"R" is freg1 & fpr1x = 1 & fr1half = 31 { export fr31R; }
|
|
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 0 { export fr0L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 1 { export fpe2; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 2 { export fpe4; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 3 { export fpe6; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 4 { export fr4L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 5 { export fr5L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 6 { export fr6L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 7 { export fr7L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 8 { export fr8L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 9 { export fr9L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 10 { export fr10L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 11 { export fr11L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 12 { export fr12L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 13 { export fr13L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 14 { export fr14L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 15 { export fr15L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 16 { export fr16L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 17 { export fr17L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 18 { export fr18L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 19 { export fr19L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 20 { export fr20L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 21 { export fr21L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 22 { export fr22L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 23 { export fr23L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 24 { export fr24L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 25 { export fr25L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 26 { export fr26L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 27 { export fr27L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 28 { export fr28L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 29 { export fr29L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 30 { export fr30L; }
|
|
FPR232: freg2^"L" is fpr2x = 0 & freg2 & fr2half = 31 { export fr31L; }
|
|
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 0 { export fr0R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 1 { export fpe3; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 2 { export fpe5; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 3 { export fpe7; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 4 { export fr4R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 5 { export fr5R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 6 { export fr6R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 7 { export fr7R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 8 { export fr8R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 9 { export fr9R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 10 { export fr10R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 11 { export fr11R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 12 { export fr12R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 13 { export fr13R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 14 { export fr14R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 15 { export fr15R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 16 { export fr16R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 17 { export fr17R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 18 { export fr18R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 19 { export fr19R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 20 { export fr20R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 21 { export fr21R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 22 { export fr22R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 23 { export fr23R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 24 { export fr24R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 25 { export fr25R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 26 { export fr26R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 27 { export fr27R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 28 { export fr28R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 29 { export fr29R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 30 { export fr30R; }
|
|
FPR232: freg2^"R" is freg2 & fpr2x = 1 & fr2half = 31 { export fr31R; }
|
|
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 0 { export fr0L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 1 { export fpe2; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 2 { export fpe4; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 3 { export fpe6; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 4 { export fr4L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 5 { export fr5L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 6 { export fr6L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 7 { export fr7L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 8 { export fr8L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 9 { export fr9L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 10 { export fr10L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 11 { export fr11L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 12 { export fr12L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 13 { export fr13L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 14 { export fr14L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 15 { export fr15L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 16 { export fr16L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 17 { export fr17L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 18 { export fr18L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 19 { export fr19L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 20 { export fr20L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 21 { export fr21L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 22 { export fr22L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 23 { export fr23L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 24 { export fr24L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 25 { export fr25L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 26 { export fr26L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 27 { export fr27L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 28 { export fr28L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 29 { export fr29L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 30 { export fr30L; }
|
|
FPRT32: fpt^"L" is fptx = 0 & fpt & fpthalf = 31 { export fr31L; }
|
|
|
|
# 32 bit fp register access, upper half (R)
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 0 { export fr0R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 1 { export fpe3; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 2 { export fpe5; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 3 { export fpe7; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 4 { export fr4R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 5 { export fr5R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 6 { export fr6R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 7 { export fr7R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 8 { export fr8R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 9 { export fr9R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 10 { export fr10R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 11 { export fr11R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 12 { export fr12R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 13 { export fr13R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 14 { export fr14R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 15 { export fr15R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 16 { export fr16R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 17 { export fr17R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 18 { export fr18R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 19 { export fr19R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 20 { export fr20R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 21 { export fr21R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 22 { export fr22R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 23 { export fr23R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 24 { export fr24R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 25 { export fr25R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 26 { export fr26R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 27 { export fr27R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 28 { export fr28R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 29 { export fr29R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 30 { export fr30R; }
|
|
FPRT32: fpt^"R" is fptx = 1 & fpt & fpthalf = 31 { export fr31R; }
|
|
|
|
|
|
fpcmp: ",FALSE?" is fpcond=0 { result:1 = 0; export result; }
|
|
fpcmp: ",false" is fpcond=1 { result:1 = 0; export result; }
|
|
fpcmp: ",?" is fpcond=2 { result:1 = 0; export result; }
|
|
fpcmp: ",!<=>" is fpcond=3 { result:1 = 0; export result; }
|
|
fpcmp: ",=" is fpcond=4 & FPR132 & FPR232 { result:1 = FPR232 f== FPR132; export result; }
|
|
fpcmp: ",=T" is fpcond=5 & FPR132 & FPR232 { result:1 = FPR232 f== FPR132; export result; }
|
|
fpcmp: ",?=" is fpcond=6 & FPR132 & FPR232 { result:1 = FPR232 f== FPR132; export result; }
|
|
fpcmp: ",!<>" is fpcond=7 & FPR132 & FPR232 { result:1 = FPR232 f== FPR132; export result; }
|
|
fpcmp: ",!?>=" is fpcond=8 & FPR132 & FPR232 { result:1 = FPR232 f< FPR132; export result; }
|
|
fpcmp: ",<" is fpcond=9 & FPR132 & FPR232 { result:1 = FPR232 f< FPR132; export result; }
|
|
fpcmp: ",?<" is fpcond=10 & FPR132 & FPR232 { result:1 = FPR232 f< FPR132; export result; }
|
|
fpcmp: ",!>=" is fpcond=11 & FPR132 & FPR232 { result:1 = FPR232 f< FPR132; export result; }
|
|
fpcmp: ",!?>" is fpcond=12 & FPR132 & FPR232 { result:1 = FPR232 f<= FPR132; export result; }
|
|
fpcmp: ",<=" is fpcond=13 & FPR132 & FPR232 { result:1 = FPR232 f<= FPR132; export result; }
|
|
fpcmp: ",?<=" is fpcond=14 & FPR132 & FPR232 { result:1 = FPR232 f<= FPR132; export result; }
|
|
fpcmp: ",!>" is fpcond=15 & FPR132 & FPR232 { result:1 = FPR232 f<= FPR132; export result; }
|
|
fpcmp: ",!?<=" is fpcond=16 & FPR132 & FPR232 { result:1 = FPR232 f> FPR132; export result; }
|
|
fpcmp: ",>" is fpcond=17 & FPR132 & FPR232 { result:1 = FPR232 f> FPR132; export result; }
|
|
fpcmp: ",?>" is fpcond=18 & FPR132 & FPR232 { result:1 = FPR232 f> FPR132; export result; }
|
|
fpcmp: ",!<=" is fpcond=19 & FPR132 & FPR232 { result:1 = FPR232 f> FPR132; export result; }
|
|
fpcmp: ",!?<" is fpcond=20 & FPR132 & FPR232 { result:1 = FPR232 f>= FPR132; export result; }
|
|
fpcmp: ",>=" is fpcond=21 & FPR132 & FPR232 { result:1 = FPR232 f>= FPR132; export result; }
|
|
fpcmp: ",?>=" is fpcond=22 & FPR132 & FPR232 { result:1 = FPR232 f>= FPR132; export result; }
|
|
fpcmp: ",!<;" is fpcond=23 & FPR132 & FPR232 { result:1 = FPR232 f>= FPR132; export result; }
|
|
fpcmp: ",!?=" is fpcond=24 & FPR132 & FPR232 { result:1 = FPR232 f!= FPR132; export result; }
|
|
fpcmp: ",<>" is fpcond=25 & FPR132 & FPR232 { result:1 = FPR232 f!= FPR132; export result; }
|
|
fpcmp: ",!=" is fpcond=26 & FPR132 & FPR232 { result:1 = FPR232 f!= FPR132; export result; }
|
|
fpcmp: ",!=T" is fpcond=27 & FPR132 & FPR232 { result:1 = FPR232 f!= FPR132; export result; }
|
|
fpcmp: ",!?" is fpcond=28 { result:1 = 1; export result; }
|
|
fpcmp: ",<=>" is fpcond=29 { result:1 = 1; export result; }
|
|
fpcmp: ",TRUE?" is fpcond=30 { result:1 = 1; export result; }
|
|
fpcmp: ",TRUE" is fpcond=31 { result:1 = 1; export result; }
|
|
|
|
fpcmp64: ",FALSE?" is fpcond=0 { result:1 = 0; export result; }
|
|
fpcmp64: ",false" is fpcond=1 { result:1 = 0; export result; }
|
|
fpcmp64: ",?" is fpcond=2 { result:1 = 0; export result; }
|
|
fpcmp64: ",!<=>;" is fpcond=3 { result:1 = 0; export result; }
|
|
fpcmp64: ",=" is fpcond=4 & FPR164 & FPR264 { result:1 = FPR264 f== FPR164; export result; }
|
|
fpcmp64: ",=T" is fpcond=5 & FPR164 & FPR264 { result:1 = FPR264 f== FPR164; export result; }
|
|
fpcmp64: ",?=" is fpcond=6 & FPR164 & FPR264 { result:1 = FPR264 f== FPR164; export result; }
|
|
fpcmp64: ",!<>" is fpcond=7 & FPR164 & FPR264 { result:1 = FPR264 f== FPR164; export result; }
|
|
fpcmp64: ",!?>=" is fpcond=8 & FPR164 & FPR264 { result:1 = FPR264 f< FPR164; export result; }
|
|
fpcmp64: ",<" is fpcond=9 & FPR164 & FPR264 { result:1 = FPR264 f< FPR164; export result; }
|
|
fpcmp64: ",?<" is fpcond=10 & FPR164 & FPR264 { result:1 = FPR264 f< FPR164; export result; }
|
|
fpcmp64: ",!>=" is fpcond=11 & FPR164 & FPR264 { result:1 = FPR264 f< FPR164; export result; }
|
|
fpcmp64: ",!?>" is fpcond=12 & FPR164 & FPR264 { result:1 = FPR264 f<= FPR164; export result; }
|
|
fpcmp64: ",<=" is fpcond=13 & FPR164 & FPR264 { result:1 = FPR264 f<= FPR164; export result; }
|
|
fpcmp64: ",?<=" is fpcond=14 & FPR164 & FPR264 { result:1 = FPR264 f<= FPR164; export result; }
|
|
fpcmp64: ",!>" is fpcond=15 & FPR164 & FPR264 { result:1 = FPR264 f<= FPR164; export result; }
|
|
fpcmp64: ",!?<=" is fpcond=16 & FPR164 & FPR264 { result:1 = FPR264 f> FPR164; export result; }
|
|
fpcmp64: ",>" is fpcond=17 & FPR164 & FPR264 { result:1 = FPR264 f> FPR164; export result; }
|
|
fpcmp64: ",?>" is fpcond=18 & FPR164 & FPR264 { result:1 = FPR264 f> FPR164; export result; }
|
|
fpcmp64: ",!<=" is fpcond=19 & FPR164 & FPR264 { result:1 = FPR264 f> FPR164; export result; }
|
|
fpcmp64: ",!?<" is fpcond=20 & FPR164 & FPR264 { result:1 = FPR264 f>= FPR164; export result; }
|
|
fpcmp64: ",>=" is fpcond=21 & FPR164 & FPR264 { result:1 = FPR264 f>= FPR164; export result; }
|
|
fpcmp64: ",?>=" is fpcond=22 & FPR164 & FPR264 { result:1 = FPR264 f>= FPR164; export result; }
|
|
fpcmp64: ",!<" is fpcond=23 & FPR164 & FPR264 { result:1 = FPR264 f>= FPR164; export result; }
|
|
fpcmp64: ",!?=" is fpcond=24 & FPR164 & FPR264 { result:1 = FPR264 f!= FPR164; export result; }
|
|
fpcmp64: ",<>" is fpcond=25 & FPR164 & FPR264 { result:1 = FPR264 f!= FPR164; export result; }
|
|
fpcmp64: ",!=" is fpcond=26 & FPR164 & FPR264 { result:1 = FPR264 f!= FPR164; export result; }
|
|
fpcmp64: ",!=T" is fpcond=27 & FPR164 & FPR264 { result:1 = FPR264 f!= FPR164; export result; }
|
|
fpcmp64: ",!?" is fpcond=28 { result:1 = 1; export result; }
|
|
fpcmp64: ",<=>" is fpcond=29 { result:1 = 1; export result; }
|
|
fpcmp64: ",TRUE?" is fpcond=30 { result:1 = 1; export result; }
|
|
fpcmp64: ",TRUE" is fpcond=31 { result:1 = 1; export result; }
|
|
|
|
|
|
#################################
|
|
# space register subconstructors
|
|
#################################
|
|
SR: "srN" is s = 0 { export 0:4; }
|
|
SR: sr1 is s = 1 & sr1 { export sr1; }
|
|
SR: sr2 is s = 2 & sr2 { export sr2; }
|
|
SR: sr3 is s = 3 & sr3 { export sr3; }
|
|
|
|
SR3bit: sr0 is srbit2=0 & srbit1=0 & srbit0=0 & sr0 { export sr0; }
|
|
SR3bit: sr1 is srbit2=0 & srbit1=0 & srbit0=1 & sr1 { export sr1; }
|
|
SR3bit: sr2 is srbit2=0 & srbit1=1 & srbit0=0 & sr2 { export sr2; }
|
|
SR3bit: sr3 is srbit2=0 & srbit1=1 & srbit0=1 & sr3 { export sr3; }
|
|
SR3bit: sr4 is srbit2=1 & srbit1=0 & srbit0=0 & sr4 { export sr4; }
|
|
SR3bit: sr5 is srbit2=1 & srbit1=0 & srbit0=1 & sr5 { export sr5; }
|
|
SR3bit: sr6 is srbit2=1 & srbit1=1 & srbit0=0 & sr6 { export sr6; }
|
|
SR3bit: sr7 is srbit2=1 & srbit1=1 & srbit0=1 & sr7 { export sr7; }
|
|
|
|
# These two are the cosmetic constructors for printing purposes
|
|
# They print out SR,RB or else just RB if the space register is determined by the lower bits of RB
|
|
# s=0 means use the least significant two bits of the address in RB as the space register selection (added to 4)
|
|
SRRB: (RB) is RB & s=0 { }
|
|
# s=1-3 means use SR1 - SR3
|
|
SRRB: (SR,RB) is SR & RB { }
|
|
|
|
# BE uses three bits for the space register
|
|
SRRB3bit: (SR3bit,RB) is SR3bit & RB { }
|
|
|
|
# these are the semantic constructors dealing with space registers
|
|
# this first one gets the value in the appropriate space register and returns it.
|
|
# it is used by LDSID.
|
|
SRVAL: SR is SR & RB & s=0 {
|
|
local selbits = (RB >> 30);
|
|
srreg:4 = &sr4 + 4 * selbits;
|
|
spc:4 = *[register] srreg;
|
|
export spc;
|
|
}
|
|
|
|
SRVAL: sr1 is sr1 & s=1 { export sr1; }
|
|
SRVAL: sr2 is sr2 & s=2 { export sr2; }
|
|
SRVAL: sr3 is sr3 & s=3 { export sr3; }
|
|
|
|
# TODO This is broken until we decide on how to handle space registers and a 64 bit extended address space
|
|
SPCBASE: is SRVAL & RB {
|
|
# space:$(ADDRSIZE) = zext(SRVAL);
|
|
off:$(ADDRSIZE) = zext(RB); # need to decide whether to remove the lower bits to hide privilege-- TODO & 0xFFFFFFFFFFFFFFFC;
|
|
# address:$(ADDRSIZE) = (space << 32) | offset;
|
|
# export address;
|
|
export off;
|
|
}
|
|
|
|
###############################################
|
|
# encodings for branches
|
|
###############################################
|
|
# 12 bit displacement encoded using assemble_12
|
|
displacement2W: target is w & w2 [ target = (1-(w*2)) * ( ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; export temp; }
|
|
#branchTarget2W: target is w & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFFF800) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; export temp; }
|
|
# this has the space register added
|
|
#branchTarget2W: target is w & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFFF800) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; temp = temp + (iasq_front<<32); export *:$(ADDRSIZE) temp; }
|
|
##### good before caret branchTarget2W: target is w & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFFF800) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { export *:$(ADDRSIZE) target; }
|
|
#branchTarget2W: target is w & w2 [
|
|
branchTarget2W: target is w & w2less2 & w2_2
|
|
[
|
|
# target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFFF800) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) );
|
|
target = inst_start + 8 + 4 * (
|
|
((-1 * w) << 11) |
|
|
(w2_2 << 10) |
|
|
w2less2
|
|
);
|
|
temp32 = branchImmDest;
|
|
branchImmDest = target;
|
|
globalset(inst_next, branchImmDest);
|
|
branchImmDest = temp32;
|
|
]
|
|
{ export *:$(ADDRSIZE) target; }
|
|
|
|
|
|
# 17 bit displacement encoded using assemble_17
|
|
#displacement3W: target is w & w1 & w2 [ target = 4 * ( (w * 0xFFFFFFFFFFFF0000) | (w1 << 11) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; export temp; }
|
|
displacement3W: target is w & w1 & w2less2 & w2_2 [ target = 4 * (
|
|
((-1 * w) << 16) |
|
|
(w1 << 11) |
|
|
(w2_2 << 10) |
|
|
w2less2
|
|
);] { temp:$(ADDRSIZE) = target; export temp; }
|
|
#branchTarget3W: target is w & w1 & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFF0000) | (w1 << 11) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; export temp; }
|
|
#branchTarget3W: target is w & w1 & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFF0000) | (w1 << 11) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { temp:$(ADDRSIZE) = target; target = target + (iasq_front << 32); export temp; }
|
|
#####good before caret branchTarget3W: target is w & w1 & w2 [ target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFF0000) | (w1 << 11) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) ); ] { export *:$(ADDRSIZE) target; }
|
|
#branchTarget3W: target is w & w1 & w2
|
|
branchTarget3W: target is w & w1 & w2less2 & w2_2
|
|
[
|
|
# target = inst_start + 8 + 4 * ( (w * 0xFFFFFFFFFFFF0000) | (w1 << 11) | ((w2 & 0x1) << 10) | ((w2>>1) & 0x3FF) );
|
|
target = inst_start + 8 + 4 * (
|
|
((-1 * w) << 16) |
|
|
(w1 << 11) |
|
|
(w2_2 << 10) |
|
|
w2less2
|
|
);
|
|
temp32 = branchImmDest;
|
|
branchImmDest = target;
|
|
globalset(inst_next, branchImmDest);
|
|
branchImmDest = temp32;
|
|
]
|
|
{ export *:$(ADDRSIZE) target; }
|
|
|
|
# simple IP relative branch
|
|
IPRelativeIndexedTarget: is RX
|
|
{
|
|
target:$(ADDRSIZE) = inst_start + (RX<<3) + 8;
|
|
branchIndDest = target;
|
|
export target;
|
|
}
|
|
|
|
# vectored (base register plus index register) branch
|
|
IndexedTarget: is RX & RB
|
|
{
|
|
target:$(ADDRSIZE) = (RX<<3) + RB;
|
|
branchIndDest = target;
|
|
export target;
|
|
}
|
|
|
|
# vectored (base register plus index register -- but index register is r0 so skip it since this is a return) branch
|
|
ReturnTarget: is RB
|
|
{
|
|
branchIndDest = RB;
|
|
export RB;
|
|
}
|
|
|
|
# generate the target address for an external branch
|
|
externalTarget: displacement3W^SRRB3bit is RB & displacement3W & SRRB3bit {
|
|
# spaceID:$(ADDRSIZE) = zext(SRVAL);
|
|
# spaceID = spaceID << 32;
|
|
# spaceID:$(ADDRSIZE) = 0;
|
|
# currently ignoring the spaceID TODO FIX THIS?
|
|
# target = spaceID + sext(RB) + sext(displacement3W);
|
|
target:$(ADDRSIZE) = sext(displacement3W) + sext(RB);
|
|
branchIndDest = target;
|
|
export target;
|
|
}
|
|
|
|
shiftC: shift is cp [ shift=31-cp; ] { amount:4 = shift; export amount; }
|
|
shiftCLen: shift is im5 [ shift=32-im5; ] { amount:4 = shift; export amount; }
|
|
|
|
#lse14: offset is sim14 & bit0 [ offset = (-1 * bit0) * ( (sim14 >> 1) & 0x1FFF ); ] { temp:4 = offset; export temp; }
|
|
#lse14: offset is sim14 & bit0 [ offset = (-1 * 0x2000 * bit0) | ( (sim14 >> 1) & 0x1FFF ); ] { temp:4 = sext(offset:4); export temp; }
|
|
lse14: off is im14less0 & bit0 [ off = ((-1 * bit0) << 13) | im14less0; ] { temp:4 = sext(off:4); export temp; }
|
|
####lse14: offset is sim14 & bit0 [ offset = (0xFFFFFFFFFFFFE000 * bit0) | ( (sim14 >> 1) & 0x1FFF ); ] { temp:4 = offset; export temp; }
|
|
|
|
#lse5: offset is sim5 & bit0 [ offset = (-1 * 0x10 * bit0) | ( (sim5 >> 1) & 0xF ); ] { temp:1 = sext(offset:1); export temp; }
|
|
lse5: off is im5less0 & bit0 [ off = ((-1 * bit0) << 4) | im5less0; ] { temp:1 = sext(off:1); export temp; }
|
|
|
|
#highlse5: offset is highIm5 & bit16 [ offset = (-1 * 0x10 * bit16) | ( (highIm5 >> 1) & 0xF ); ] { temp:1 = offset; export temp; }
|
|
highlse5: off is highIm5less16 & bit16 [ off = ((-1 * bit16) << 4) | highIm5less16; ] { temp:1 = off; export temp; }
|
|
|
|
#lse21: offset is sim21 [ offset = ( ((sim21 & 0x1) * 0xFFFFFFFFFFF00000) | ((sim21 & 0xFFE) << 8) | ((sim21 & 0xC000) >> 7) | ((sim21 & 0x1F0000) >> 14) | ((sim21 & 0x3000) >> 12) ) << 11 ; ] { temp:$(REGSIZE) = offset; export temp; }
|
|
lse21: off is im21less0 & bit0 & im21_1_12 & im21_12_14 & im21_14_16 & im21_16_21 [
|
|
off = (
|
|
((-1 * bit0) << 20) |
|
|
(im21_1_12 << 9) |
|
|
(im21_14_16 << 7) |
|
|
(im21_16_21 << 2) |
|
|
im21_12_14
|
|
) << 11;
|
|
] { temp:$(REGSIZE) = off; export temp; }
|
|
|
|
# Note for the im11 11-bit immediate, the sign is in bit 0, and the rest of the value is in bit 1 to 10.
|
|
# Negative numbers are stored 2s complement, with bit0 set to 1.
|
|
#
|
|
# Need to set temp32 to lse11 since the value of lse11 does not propogate so well to uplevel tables, maybe a compiler bug
|
|
#
|
|
#lse11: immed is im11 & bit0
|
|
lse11: immed is im11less0 & bit0
|
|
[ immed = ((-1*bit0) << 10) | im11less0; temp32 = immed; ]
|
|
# [ immed = (bit0 * 0xFFFFFFFFFFFFFC00) | ( (im11 >> 1) & 0x3FF ); temp32 = immed; ]
|
|
{ temp:4 = immed; export temp; }
|
|
|
|
OFF_BASE_14: lse14^SRRB is lse14 & SRRB & SPCBASE { temp:$(ADDRSIZE) = SPCBASE + sext(lse14); export temp; }
|
|
|
|
#############################
|
|
# condition codes
|
|
#############################
|
|
|
|
# shift conditions. There are no inverted forms of these conditions.
|
|
ShiftCond: is c=0 { export 0:1; } # never
|
|
ShiftCond: is c=1 & RT { tmp:1 = (nullifyCondResult == 0) ; export tmp; } # equal
|
|
ShiftCond: is c=2 & RT { tmp:1 = ((nullifyCondResult & (1:$(REGSIZE) << $(REGSIZE)-1)) != 0) ; export tmp; } # leftmost bit is one
|
|
ShiftCond: is c=3 & RT { tmp:1 = ((nullifyCondResult & 0x1) != 0) ; export tmp; } # rightmost bit is 1 (odd)
|
|
ShiftCond: is c=4 { export 1:1; } # always
|
|
ShiftCond: is c=5 & RT { tmp:1 = (nullifyCondResult != 0) ; export tmp; } # some bits are one
|
|
ShiftCond: is c=6 & RT { tmp:1 = ((nullifyCondResult & (1:$(REGSIZE) << $(REGSIZE)-1)) == 0) ; export tmp; } # leftmost bit is zero
|
|
ShiftCond: is c=7 & RT { tmp:1 = ((nullifyCondResult & 0x1) == 0) ; export tmp; } # rightmost bit is zero (even)
|
|
|
|
ShiftCondNullify: is c=0 { }
|
|
ShiftCondNullify: is ShiftCond [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = ShiftCond;
|
|
}
|
|
|
|
# deposit conditions. There are no inverted forms of these conditions.
|
|
DepCond: is c=0 { export 0:1; } # never
|
|
DepCond: is c=1 { tmp:1 = (nullifyCondResult == 0) ; export tmp; } # equal
|
|
DepCond: is c=2 { tmp:1 = (nullifyCondResult s< 0) ; export tmp; } # leftmost bit is one (< 0)
|
|
DepCond: is c=3 { tmp:1 = ((nullifyCondResult & 0x1) == 1) ; export tmp; } # rightmost bit is 1 (odd)
|
|
DepCond: is c=4 { export 1:1; } # always
|
|
DepCond: is c=5 { tmp:1 = (nullifyCondResult != 0) ; export tmp; } # some bits are one
|
|
DepCond: is c=6 { tmp:1 = (nullifyCondResult s>= 0) ; export tmp; } # leftmost bit is zero (>=)
|
|
DepCond: is c=7 { tmp:1 = ((nullifyCondResult & 0x1) == 0) ; export tmp; } # rightmost bit is zero (even)
|
|
|
|
DepCondNullify: is c=0 { }
|
|
DepCondNullify: is DepCond [nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = DepCond;
|
|
}
|
|
|
|
# extract conditions. The extract ops target R1, not R2 like deposit does
|
|
ExtrCond: is c=0 { export 0:1; } # never
|
|
ExtrCond: is c=1 { tmp:1 = (nullifyCondResult == 0) ; export tmp; } # equal
|
|
ExtrCond: is c=2 { tmp:1 = ((nullifyCondResult & (1:$(REGSIZE) << $(REGSIZE)-1)) != 0) ; export tmp; } # leftmost bit is one
|
|
ExtrCond: is c=3 { tmp:1 = ((nullifyCondResult & 0x1) != 0) ; export tmp; } # rightmost bit is 1 (odd)
|
|
ExtrCond: is c=4 { export 1:1; } # always
|
|
ExtrCond: is c=5 { tmp:1 = (nullifyCondResult != 0) ; export tmp; } # some bits are one
|
|
ExtrCond: is c=6 { tmp:1 = ((nullifyCondResult & (1:$(REGSIZE) << $(REGSIZE)-1)) == 0) ; export tmp; } # leftmost bit is zero
|
|
ExtrCond: is c=7 { tmp:1 = ((nullifyCondResult & 0x1) == 0) ; export tmp; } # rightmost bit is zero (even)
|
|
|
|
ExtrCondNullify: is c=0 { }
|
|
ExtrCondNullify: is ExtrCond [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = ExtrCond;
|
|
}
|
|
|
|
|
|
# a subset of the SED conditions used for bit tests
|
|
BVBCond: is c=2 & R1 { tmp:1 = ((R1 >> (31-sar)) & 0x1) == 1 ; export tmp; } # target bit is one
|
|
BVBCond: is c=6 & R1 { tmp:1 = ((R1 >> (31-sar)) & 0x1) == 0 ; export tmp; } # target bit is zero
|
|
|
|
BBCond: is c=2 & R1 & bboffset { tmp:1 = ((R1 >> (31-bboffset)) & 0x1) == 1 ; export tmp; } # target bit is one
|
|
BBCond: is c=6 & R1 & bboffset { tmp:1 = ((R1 >> (31-bboffset)) & 0x1) == 0 ; export tmp; } # target bit is zero
|
|
|
|
#
|
|
# unit conditions for checking byte ranges within a word
|
|
#
|
|
RegUnitCond: is c=0 { export 0:1; } # never
|
|
RegUnitCond: is c=2 & RT { tmp:1 = (RT:1 == 0) || ((RT:2 & 0xFF00) == 0) || ((RT:3 & 0xFF0000) == 0) || ((RT & 0xFF000000) == 0) ; export tmp; } # some byte zero
|
|
RegUnitCond: is c=3 & RT { tmp:1 = ((RT:2 & 0xFFFF) == 0) || ((RT & 0xFFFF0000) == 0) ; export tmp; } # some halfword zero
|
|
RegUnitCond: is c=4 { export 0:1; } # some digit carry -- TODO FIGURE OUT BCD
|
|
RegUnitCond: is c=6 { export 0:1; } # some byte carry -- TODO BCD
|
|
RegUnitCond: is c=7 { export 0:1; } # some halfword carry -- TODO BCD
|
|
|
|
UnitCond: "" is RegUnitCond & fv=0 { export RegUnitCond; }
|
|
UnitCond: "" is RegUnitCond & fv=1 { tmp:1 = ! RegUnitCond; export tmp; }
|
|
|
|
UnitCondNullify: is c=0 & fv=0 { }
|
|
UnitCondNullify: is UnitCond [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = UnitCond;
|
|
}
|
|
|
|
UnitCondSym: RegUnitCondSym is RegUnitCondSym & fv=0 { }
|
|
UnitCondSym: InvUnitCondSym is InvUnitCondSym & fv=1 { }
|
|
|
|
#
|
|
##### The Add Conditions from table 5-4 on page 5-5
|
|
#
|
|
RegAddCond: is c = 0 { export 0:1; } # never
|
|
RegAddCond: is c = 1 & R1 & R2 { tmp:1 = (R1 == R2) ; export tmp; } # equal
|
|
RegAddCond: is c = 2 & R1 & R2 { tmp:1 = (R1 s< -R2) ; export tmp; } # signed less than negative of R2
|
|
RegAddCond: is c = 3 & R1 & R2 { tmp:1 = (R1 s<= R2) ; export tmp; } # signed less than or equal to R2
|
|
RegAddCond: is c = 4 & R1 & R2 { tmp:1 = ! carry(R1,R2) ; export tmp; } # unsigned sum does not overflow
|
|
RegAddCond: is c = 5 & R1 & R2 { tmp:1 = (R1 + R2) == 0 ; export tmp; } # sum is zero or no overflow (why two definitions??)
|
|
RegAddCond: is c = 6 & R1 & R2 { tmp:1 = scarry(R1,R2); export tmp; } # signed sum overflows
|
|
RegAddCond: is c = 7 & R1 & R2 { tmp:1 = ((R1+R2) & 0x1) == 0x1 ; export tmp; } # sum is odd
|
|
|
|
AddCond: is RegAddCond & fv=0 { export RegAddCond; }
|
|
AddCond: is RegAddCond & fv=1 { tmp:1 = ! RegAddCond; export tmp; }
|
|
|
|
AddCondNullify: is c=0 & fv=0 { }
|
|
AddCondNullify: is AddCond [ nullifyEnable=1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = AddCond;
|
|
}
|
|
|
|
AddCondSym: RegAddCondSym is RegAddCondSym & fv=0 { }
|
|
AddCondSym: InvAddCondSym is InvAddCondSym & fv=1 { }
|
|
|
|
RegAddCondI: is c = 0 { export 0:1; } # never
|
|
RegAddCondI: is c = 1 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = (val == -R2) ; export tmp; } # equal to negated
|
|
RegAddCondI: is c = 2 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = (val s< -R2) ; export tmp; } # signed less than negated R2
|
|
RegAddCondI: is c = 3 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = (val s<= -R2) ; export tmp; } # signed less than or equal to R2
|
|
RegAddCondI: is c = 4 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = ! carry(val,R2) ; export tmp; } # unsigned sum does not overflow
|
|
RegAddCondI: is c = 5 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = (val + R2) == 0 ; export tmp; } # sum is zero or no overflow (why two definitions??)
|
|
RegAddCondI: is c = 6 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = scarry(val,R2); export tmp; } # signed sum overflows
|
|
RegAddCondI: is c = 7 & highlse5 & R2 { val:$(REGSIZE) = sext(highlse5:1); tmp:1 = ((val+R2) & 0x1) == 0x1 ; export tmp; } # sum is odd
|
|
|
|
|
|
# Some notes-
|
|
# lse11 is derived from an 11-bit immediate, so we need to take 2 bytes, not 1 byte as in the original coding
|
|
# R2 must sometimes be negated before the comparison, as per the manual, Table 5-4
|
|
# The arithmetic comparison must be performed on a larger size temp than the original, so that negating 0x80000000 works correctly
|
|
# temp32 is used because the value of lse11 in the pcode does not flow so well to here - maybe a compiler bug?
|
|
#
|
|
|
|
RegAddCondI11: is c = 0 { export 0:1; } # never
|
|
|
|
RegAddCondI11: is temp32 & c = 1 & lse11 & R2 {
|
|
val:8 = sext(temp32:2); tmp_R2:8 = sext(R2);
|
|
tmp:1 = (val == -tmp_R2) ; export tmp; } # equal
|
|
|
|
RegAddCondI11: is temp32 & c = 2 & lse11 & R2 {
|
|
val:8 = sext(temp32:2); tmp_R2:8 = sext(R2);
|
|
tmp:1 = (val s< -tmp_R2) ; export tmp; } # signed less than negative of R2
|
|
|
|
RegAddCondI11: is temp32 & c = 3 & lse11 & R2 {
|
|
val:8 = sext(temp32:2); tmp_R2:8 = sext(R2);
|
|
tmp:1 = (val s<= -tmp_R2) ; export tmp; } # signed less than or equal to R2
|
|
|
|
RegAddCondI11: is temp32 & c = 4 & lse11 & R2 {
|
|
val:$(REGSIZE) = sext(temp32:2);
|
|
tmp:1 = ! carry(val,R2) ; export tmp; } # unsigned sum does not overflow
|
|
|
|
RegAddCondI11: is temp32 & c = 5 & lse11 & R2 {
|
|
# Don't need 64-bit arithmetic here
|
|
val:$(REGSIZE) = sext(temp32:2);
|
|
tmp:1 = (val + R2) == 0 ; export tmp; } # sum is zero or no overflow (why two definitions??)
|
|
|
|
RegAddCondI11: is temp32 & c = 6 & lse11 & R2 {
|
|
val:$(REGSIZE) = sext(temp32:2);
|
|
tmp:1 = scarry(val,R2); export tmp; } # signed sum overflows
|
|
|
|
RegAddCondI11: is temp32 & c = 7 & lse11 & R2 {
|
|
val:8 = sext(temp32:2); tmp_R2:8 = sext(R2);
|
|
tmp:1 = ((val+tmp_R2) & 0x1) == 0x1 ; export tmp; } # sum is odd
|
|
|
|
AddCondI11: is RegAddCondI11 & fv=0 { export RegAddCondI11; }
|
|
AddCondI11: is RegAddCondI11 & fv=1 { temp:1 = ! RegAddCondI11; export temp; }
|
|
|
|
AddCondI11Nullify: is c=0 & fv=0 { }
|
|
AddCondI11Nullify: is AddCondI11 [ nullifyEnable=1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = AddCondI11;
|
|
}
|
|
|
|
#
|
|
#### Compare / Subtract Instructions
|
|
#
|
|
RegCSCond: is c=0 & R1 & R2 { export 0:1; } # never
|
|
RegCSCond: is c=1 & R1 & R2 { tmp:1 = (R1 == R2) ; export tmp; } # equal
|
|
RegCSCond: is c=2 & R1 & R2 { tmp:1 = (R1 s< R2) ; export tmp; } # signed less than
|
|
RegCSCond: is c=3 & R1 & R2 { tmp:1 = (R1 s<= R2) ; export tmp; } # signed less than equal
|
|
RegCSCond: is c=4 & R1 & R2 { tmp:1 = (R1 < R2) ; export tmp; } # unsigned less than
|
|
RegCSCond: is c=5 & R1 & R2 { tmp:1 = (R1 <= R2) ; export tmp; } # unsigned less than equal
|
|
RegCSCond: is c=6 & R1 & R2 { tmp:1 = sborrow(R1,R2) ; export tmp; } # signed minus overflows (borrows)
|
|
RegCSCond: is c=7 & R1 & R2 { tmp:1 = ((R1 - R2) & 0x1) == 1 ; export tmp; } # odd
|
|
|
|
CSCond: is fv=0 & RegCSCond { export RegCSCond; }
|
|
CSCond: is fv=1 & RegCSCond { tmp:1 = ! RegCSCond; export tmp; }
|
|
|
|
CSCondNullify: is c=0 & fv=0 { }
|
|
CSCondNullify: is CSCond [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = CSCond;
|
|
}
|
|
|
|
CSCondSym: RegCSCondSym is RegCSCondSym & fv=0 { }
|
|
CSCondSym: InvCSCondSym is InvCSCondSym & fv=1 { }
|
|
|
|
# The Compare or Subtract conditions compared with 5 bit immediates
|
|
# This is used in the COMIB[TF] instructions. The inverted versions are never used.
|
|
RegCSCondI: is c=0 & R2 & highlse5 { export 0:1; } # never
|
|
RegCSCondI: is c=1 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = (val == R2) ; export tmp; } # equal
|
|
RegCSCondI: is c=2 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = (val s< R2) ; export tmp; } # signed less than
|
|
RegCSCondI: is c=3 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = (val s<= R2) ; export tmp; } # signed less than equal
|
|
RegCSCondI: is c=4 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = (val < R2) ; export tmp; } # unsigned less than
|
|
RegCSCondI: is c=5 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = (val <= R2) ; export tmp; } # unsigned less than equal
|
|
RegCSCondI: is c=6 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); local diff = (val - R2); tmp:1 = (val s> 0 && R2 s> 0 && diff s< 0) || (val s< 0 && R2 s< 0 && diff s> 0) ; export tmp; } # overflow
|
|
RegCSCondI: is c=7 & R2 & highlse5 { val:$(REGSIZE) = sext(highlse5); tmp:1 = ((val - R2) & 0x1) == 1 ; export tmp; } # odd
|
|
|
|
# The Compare or Subtract conditions compared with 11 bit immediates. These are used with the SUBI[O] and COMICLR instructions. Both regular and inverted forms are used.
|
|
RegCSCondI11: is c=0 & R2 & lse11 { export 0:1; } # never
|
|
RegCSCondI11: is c=1 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = (val == R2) ; export tmp; } # equal
|
|
RegCSCondI11: is c=2 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = (val s< R2) ; export tmp; } # signed less than
|
|
RegCSCondI11: is c=3 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = (val s<= R2) ; export tmp; } # signed less than equal
|
|
RegCSCondI11: is c=4 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = (val < R2) ; export tmp; } # unsigned less than
|
|
RegCSCondI11: is c=5 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = (val <= R2) ; export tmp; } # unsigned less than equal
|
|
RegCSCondI11: is c=6 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); local diff = (val - R2); tmp:1 = (val s> 0 && R2 s> 0 && diff s< 0) || (val s< 0 && R2 s< 0 && diff s> 0) ; export tmp; } # overflow
|
|
RegCSCondI11: is c=7 & R2 & lse11 { val:$(REGSIZE) = sext(lse11); tmp:1 = ((val - R2) & 0x1) == 1 ; export tmp; } # odd
|
|
|
|
CSCondI11: is RegCSCondI11 & fv=0 { export RegCSCondI11; }
|
|
CSCondI11: is RegCSCondI11 & fv=1 { temp:1 = ! RegCSCondI11; export temp; }
|
|
|
|
CSCondI11Nullify: is c=0 & fv=0 { }
|
|
CSCondI11Nullify: is CSCondI11 [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = CSCondI11;
|
|
}
|
|
|
|
#
|
|
#### Logical Conditions
|
|
#
|
|
RegLogicCond: is c=0 { export 0:1; } # never
|
|
RegLogicCond: is c=1 & RT { tmp:1 = (RT == 0) ; export tmp; } # equal, all zeros
|
|
RegLogicCond: is c=2 & RT { tmp:1 = (RT & 0x80000000) != 0 ; export tmp; } # <, leftmost bit is 1
|
|
RegLogicCond: is c=3 & RT { tmp:1 = ((RT & 0x80000000) != 0) || RT == 0 ; export tmp; } # <=, leftmost bit is 1 or all bits are zero
|
|
RegLogicCond: is c=7 & RT { tmp:1 = (RT & 0x1) == 0x1; export tmp; } # odd, rightmost bit is 1
|
|
|
|
LogicCond: is fv=0 & RegLogicCond { tmp:1 = RegLogicCond; export tmp; } # non-inverted cases
|
|
LogicCond: is fv=1 & RegLogicCond { tmp:1 = ! RegLogicCond; export tmp; } # inverted cases
|
|
|
|
LogicCondSym: RegLogicCondSym is RegLogicCondSym & fv=0 { }
|
|
LogicCondSym: InvLogicCondSym is InvLogicCondSym & fv=1 { }
|
|
|
|
LogicCondNullify: is c=0 & fv=0 { }
|
|
LogicCondNullify: is LogicCond [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ]
|
|
{
|
|
nullifyNextCond = LogicCond;
|
|
}
|
|
|
|
##########################################
|
|
# Completers from the tables in chapter 5
|
|
##########################################
|
|
|
|
# Table 5-11 on page 5-22
|
|
# The shifted form for byte doesn't shift, as byte addressing is single byte aligned
|
|
indexedByteAccessCmplt: is u=0 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(RX); export off; } # none
|
|
indexedByteAccessCmplt: ",M" is u=0 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + RX; export off; } # M, modify, post inc by RX
|
|
indexedByteAccessCmplt: ",S" is u=1 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(RX); export off; } # S, shift left by 2
|
|
indexedByteAccessCmplt: ",SM" is u=1 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(RX); export off; } # SM, shift and modify
|
|
|
|
# The shifted form for halfword shifts by 2 bytes, since that is the size of a halfword
|
|
indexedHalfwordAccessCmplt: is u=0 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(RX); export off; } # none
|
|
indexedHalfwordAccessCmplt: ",M" is u=0 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + RX; export off; } # M, modify, post inc by RX
|
|
indexedHalfwordAccessCmplt: ",S" is u=1 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext((RX << 1)); export off; } # S, shift left by 1
|
|
indexedHalfwordAccessCmplt: ",SM" is u=1 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(RX << 1); export off; } # SM, shift and modify
|
|
|
|
# The shifted form for words shifts by 2 (x4), since words are aligned on 4 and increment by 4
|
|
indexedWordAccessCmplt: is u=0 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(RX); export off; } # none
|
|
indexedWordAccessCmplt: ",M" is u=0 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + RX; export off; } # M, modify, post inc by RX
|
|
indexedWordAccessCmplt: ",S" is u=1 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext((RX << 2)); export off; } # S, shift left by 2
|
|
indexedWordAccessCmplt: ",SM" is u=1 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(RX << 2); export off; } # SM, shift and modify
|
|
|
|
# same as above, but shifts by 3 bits. Used for the LDCWX instruction
|
|
indexedDoublewordAccessCmplt: is u=0 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(RX); export off; } # none
|
|
indexedDoublewordAccessCmplt: ",M" is u=0 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + RX; export off; } # M, modify, post inc by RX
|
|
indexedDoublewordAccessCmplt: ",S" is u=1 & m=0 & RX & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext((RX << 3)); export off; } # S, shift left by 3 NOTE YES THIS IS 3
|
|
indexedDoublewordAccessCmplt: ",SM" is u=1 & m=1 & RX & RB & SPCBASE { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(RX << 3); export off; } # SM, shift and modify
|
|
|
|
# Table 5-12 on Page 5-24
|
|
# these are for loads, e.g. ldws
|
|
shortDispCmplt: is m=0 & highlse5 & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(highlse5); export off; } # no modification
|
|
shortDispCmplt: ",MA" is u=0 & m=1 & RB & RX & SPCBASE & highlse5 { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(highlse5); export off; } # modify after
|
|
shortDispCmplt: ",MB" is u=1 & m=1 & RB & RX & SPCBASE & highlse5 { local lse = sext(highlse5); off:$(ADDRSIZE) = SPCBASE + sext(lse); RB = RB + lse; export off; } # modify before
|
|
|
|
# short displacement for stores, e.g. stws
|
|
storeShortDispCmplt: is m=0 & lse5 & SPCBASE { off:$(ADDRSIZE) = SPCBASE + sext(lse5); export off; } # no modification
|
|
storeShortDispCmplt: ",MA" is u=0 & m=1 & RB & RX & SPCBASE & lse5 { off:$(ADDRSIZE) = SPCBASE; RB = RB + sext(lse5); export off; } # modify after
|
|
storeShortDispCmplt: ",MB" is u=1 & m=1 & RB & RX & SPCBASE & lse5 { local lse = sext(lse5); off:$(ADDRSIZE) = SPCBASE + sext(lse); RB = RB + lse; export off; } # modify before
|
|
|
|
# Table 5-13 on page 5-26
|
|
storeBytesShortCmplt: is u=0 & m=0 & SPCBASE & lse5 { off:$(ADDRSIZE) = SPCBASE + sext(lse5); export off; } # none / beginning, don't modify base register
|
|
storeBytesShortCmplt: ",BM" is u=0 & m=1 & SPCBASE & RR & lse5 { off:$(ADDRSIZE) = SPCBASE + sext(lse5); RR = (RR + sext(lse5)) & 0xFFFFFFFC; export off; } # beginning, modify base register
|
|
storeBytesShortCmplt: ",E" is u=1 & m=0 & SPCBASE & lse5 { off:$(ADDRSIZE) = SPCBASE + sext(lse5); export off; } # ending, don't modify
|
|
storeBytesShortCmplt: ",EM" is u=1 & m=1 & SPCBASE & RR & lse5 { off:$(ADDRSIZE) = SPCBASE + sext(lse5); RR = (RR + sext(lse5)) & 0xFFFFFFFC; export off; } # ending, modify
|
|
|
|
# u fixed at 0, Table 5-11 on page 5-22, for LPA and related system level opcodes
|
|
sysCmplt: is m=0 { }
|
|
sysCmplt: ",M" is m=1 { }
|
|
|
|
# Table 5-8 on page 5-17
|
|
loadCC: is cc=0 { }
|
|
loadCC: ",SL" is cc=2 { }
|
|
|
|
# Table 5-9 on page 5-18
|
|
storeCC: is cc=0 { }
|
|
storeCC: ",BC" is cc=1 { }
|
|
storeCC: ",SL" is cc=2 { }
|
|
|
|
# Table 5-10 on page 5-18
|
|
loadClearCC: is cc=0 { }
|
|
loadClearCC: ",CO" is cc=1 { }
|
|
|
|
# nullification as used with branches
|
|
#####nullifyForBranch: is n=0 { export 0:1; }
|
|
#####nullifyForBranch: ",N" is n=1 { export 1:1; }
|
|
# caret versions
|
|
nullifyForBranch: is n=0 { export 0:1; }
|
|
nullifyForBranch: ",N" is n=1 [ nullifyEnable = 1; globalset(inst_next, nullifyEnable); ] { export 1:1; }
|
|
|
|
nullifySymForBranch: is n=0 { }
|
|
nullifySymForBranch: ",N" is n=1 { }
|
|
|
|
# nullification as used with special function unit ops
|
|
nullifyForSpecial: is spn=0 { }
|
|
nullifyForSpecial: ",N" is spn=1 { }
|
|
|
|
# Floating point completers
|
|
#csize: "SGL" is fpsize=0 & opfam=0x0C { }
|
|
#csize: "DBL" is fpsize=1 & opfam=0x0C { }
|
|
#csize: "QUAD" is fpsize=3 & opfam=0x0C { }
|
|
|
|
#esize: "SGL" is fpsize=0 & opfam=0x0E { }
|
|
#esize: "DBL" is fpsize=1 & opfam=0x0E { }
|
|
|
|
SFU: sfu is sfu { }
|
|
|
|
|