# 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 ; build instruction; nullifyCond=nullifyNextCond; } # # 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 ; call immediateDest; 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 ; call 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=0 & instruction & immediateDest [ phase=1; ] { nullifyNextCond=0; local previousBranchCond = branchCond; branchCond = 0; branchExecuted = 0; build instruction; if ( ! (previousBranchCond) ) goto ; call immediateDest; 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 ; goto [branchIndDest]; 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 ; call [branchIndDest]; 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 ; goto [branchIndDest]; 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 ; goto [branchIndDest]; 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 ; call [branchIndDest]; 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 ; call [branchIndDest]; 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 ; build instruction; 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 ; build instruction; 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 ; build instruction; if ( ! previousBranchExecuted ) goto ; call immediateDest; 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 ; build instruction; 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 ; build instruction; 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 ; build instruction; 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 ; build instruction; if ( ! (previousBranchCond && previousBranchExecuted) ) goto ; call immediateDest; 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 ; build instruction; if ( ! previousBranchCond ) goto ; call immediateDest; 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 ; build instruction; if ( ! previousBranchExecuted ) goto ; goto [branchIndDest]; 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 ; build instruction; 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 ; build instruction; if ( ! previousBranchExecuted ) goto ; call [branchIndDest]; 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 ; build instruction; 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 ; build instruction; if ( ! previousBranchExecuted || ! previousBranchCond) goto ; goto [branchIndDest]; 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 ; build instruction; if ( ! previousBranchCond) goto ; goto [branchIndDest]; 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 ; build instruction; if ( ! previousBranchExecuted || ! previousBranchCond) goto ; call [branchIndDest]; 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 ; build instruction; if ( ! previousBranchCond ) goto ; call [branchIndDest]; 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 >> ($(REGSIZE)*8 - 1)) & 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 >> ($(REGSIZE)*8 - 1)) & 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 >> ($(REGSIZE)*8 - 1)) & 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 >> ($(REGSIZE)*8 - 1)) & 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 { }