{File name LispUnboxed.mc Description: DandeLion InterLisp Emulator Unboxed Floating Point OpCodes Author: Charnley Last modified: Charnley 5-Jun-84 16:23:45 Created: 1-Jun-84 11:02:56 } { @UNBOX2 two byte opcode = 355 Two argument opcodes Alpha byte defines one of the following operations: {10 clicks} 0 UFADD unboxed floating add {10 clicks} 1 UFSUB unboxed floating subtract {1st minus 2nd} {10 clicks} 2 UFISUB unboxed floating subtract {2nd minus 1st} {10 clicks} 3 UFMULT unboxed floating multiply {ufn} 4 UFDIV unboxed floating divide {11 clicks} 5 UGREAT unboxed floating compare {returns T or NIL} {11 clicks} 6 UMAX unboxed floating maximum {11 clicks} 7 UMIN unboxed floating minimum @UNBOX1 two byte opcode = 354 Single argument opcodes Alpha byte defines one of the following operations: {39 clicks} 0 UTOB convert unboxed to boxed {always returns boxed floating point number} {sm 8, fl 12, fx ??} 1 BTOU convert boxed to unboxed {will coerce fixed point numbers} { 4 clicks} 2 UABS unboxed floating absolute value { 4 clicks} 3 UNEG unboxed floating negative value } Set[UF2.add, 0], Set[UF2.sub, 1], Set[UF2.isub, 2], Set[UF2.mult, 3], Set[UF2.div, 4], Set[UF2.great, 5], Set[UF2.max, 6], Set[UF2.min, 7], Set[UF1.utob, 0], Set[UF1.btou, 1], Set[UF1.abs, 2], Set[UF1.neg, 3]; {Set[L3.utob, 7];{for CreateCell}} {@UNBOX2: opcode[355'b], Bank _ LUBank, c1; uTOS _ TOS, c2; uTOSH _ TOSH, CROSS[UB2Start], c3; } FloatNop, c1, at[UB2Start];{clear pending unloads} FloatNop, c2; , c3; FloatMode.RN.AI.FAST, FloatFLOW, c1; FloatAB _ TOSH LRot0, c2; Xbus _ ibNA, XDisp, L2 _ 0, c3; MAR _ [rhS, S - 1], DISP4[FOP2op], c1; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.add, 10, FOP2op]; TT _ FloatA _ MD, FLPlus, GOTO[FOPtail], c3; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.sub, 10, FOP2op]; TT _ FloatA _ MD, FLAMinusB, GOTO[FOPtail], c3; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.isub, 10, FOP2op]; TT _ FloatA _ MD, FLBMinusA, GOTO[FOPtail], c3; FOPtail: MAR _ [rhS, S + 0], c1; , c2; Rx _ FloatA _ MD, c3; FloatStartFlow, c1; , c2; , c3; PC _ PC + 1, c1; FloatUnloadS, Float.M, c2; FloatUnloadS, Float.M, c3; {Q _ PPort, }GOTO[FOPend], c1; FOPend: {Ybus _ Q, YDisp}, c2; S _ S - 2, DISP4[illegal?, 9], L2Disp, c3; Xbus _ ib, DISP4[FOP2end], c1, at[9, 10, illegal?]; TOSH _ FloatResult, GOTO[FOP2normend], c2, at[UF2.add, 10, FOP2end]; TOSH _ FloatResult, GOTO[FOP2normend], c2, at[UF2.sub, 10, FOP2end]; TOSH _ FloatResult, GOTO[FOP2normend], c2, at[UF2.isub, 10, FOP2end]; FOP2normend: TOS _ FloatResult, c3; FOP2Exit: Bank _ EmuBank, c1; IBDisp, L2 _ L2.0, c2; DISPNI[OpTable], L2 _ L2.0, c3; S _ S + 2, CANCELBR[dataerr, 0F], c1, at[0B, 10, illegal?]; S _ S + 2, CANCELBR[dataerr, 0F], c1, at[0D, 10, illegal?]; S _ S + 2, CANCELBR[dataerr, 0F], c1, at[0F, 10, illegal?]; dataerr: PC _ PC - 1, GOTO[ufnX3], c2; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.mult, 10, FOP2op]; TT _ FloatA _ MD, FLTimes.A.B, c3; MAR _ [rhS, S + 0], c1; , c2; Rx _ FloatA _ MD, c3; FloatStartFlow, c1; , c2; , c3; PC _ PC + 1, c1; FloatUnloadP, Float.M, c2; FloatUnloadP, Float.M, c3; {Q _ PPort, }GOTO[FOPend], c1; CANCELBR[ufnX3, 3], c2, at[UF2.div, 10, FOP2op]; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.max, 10, FOP2op]; TT _ FloatA _ MD, FLBMinusA, GOTO[FOPtail], c3; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.min, 10, FOP2op]; TT _ FloatA _ MD, FLAMinusB, GOTO[FOPtail], c3; Q _ FloatResult, GOTO[FOP2maxend], c2, at[UF2.max, 10, FOP2end]; Q _ FloatResult, GOTO[FOP2maxend], c2, at[UF2.min, 10, FOP2end]; FOP2maxend: Ybus _ Q, NegBr, c3; BRANCH[FOP2noswap, FOP2swap], c1; FOP2swap: TOSH _ TT, c2; TOS _ Rx, GOTO[FOP2Exit], c3; FOP2noswap: , c2; GOTO[FOP2Exit], c3; FloatAB _ TOS LRot0, CANCELBR[$, 2], c2, at[UF2.great, 10, FOP2op]; TT _ FloatA _ MD, FLAMinusB, GOTO[FOPtail], c3; Q _ FloatResult, GOTO[FOP2greatend], c2, at[UF2.great, 10, FOP2end]; FOP2greatend: Ybus _ Q, NegBr, c3; BRANCH[FOP2NIL, FOP2T], c1; FOP2NIL: TOS _ 0, GOTO[FOP2GExit], c2; FOP2T: TOS _ KTval, c2; FOP2GExit: TOSH _ 0, GOTO[FOP2Exit], c3; {@UNBOX1: opcode[354'b], Bank _ LUBank, c1; uTOS _ TOS, c2; uTOSH _ TOSH, CROSS[UB1Start], c3; } at[UB1Start], Xbus _ ibNA, XDisp, c1; DISP4[UB1fn], FloatNop, c2; {unboxed to boxed} at[UF1.utob, 10, UB1fn], uNewValLo _ TOS, L1 _ L1.fixFV, c3; Bank _ EmuBank, c1; uNewValHi _ TOSH, L3 _ L3.utob, c2; Q _ LS4FptType, CROSS[CCEntry], c3; {abs of unboxed} at[UF1.abs, 10, UB1fn], Rx _ RShift1 Rx xor ~Rx, SE _ 0, c3; TOSH _ TOSH and Rx, c1; UBSend: Xbus _ ib, c2; PC _ PC + 1, GOTO[FOP2Exit], c3; {neg of unboxed} at[UF1.neg, 10, UB1fn], Rx _ RShift1 0, SE _ 1, c3; TOSH _ TOSH xor Rx, GOTO[UBSend], c1; {boxed to unboxed} at[UF1.btou, 10, UB1fn], { GOTO[ufnX1], c3;} Ybus _ TOSH xor smallpl, ZeroBr, L2 _ L2.btou, c3; Ybus _ TOSH xor smallpl, ZeroBr, BRANCH[$, btouSP], c1; TT _ TOS, BRANCH[$, btouSN], c2; Rx _ TOSH, GOTO[GetFPT], c3; PC _ PC + 1, c1, at[L2.btou, 10, FptGetRet]; Xbus _ ib, c2; GOTO[FOP2Exit], c3; {convert small integers to floating point} btouSP: CANCELBR[$], c2; ufloat _ 0, GOTO[smallconv], c3; btouSN: ufloat _ S xor ~S, GOTO[smallconv], c3; smallconv: FloatMode.RN.AI.FAST, FloatFLOW, c1; FloatAB _ ufloat, FLFloatA, c2; FloatAB _ uTOS, c3; FloatStartFlow, c1; , c2; , c3; PC _ PC + 1, c1; FloatUnloadS, Float.M, c2; FloatUnloadS, Float.L, c3; Xbus _ ib, c1; TOSH _ FloatResult, GOTO[FOP2normend], c2; { GET FLOATING POINT NUMBER setup: argument in Rx,,TT TOS and TOSH saved in uTOS and uTOSH L2 has return value returns: TOSH,,TOS contain the floating point number TT contains LRot1 (TOSH) L0 and L1 are trashed Q, Rx and TT are trashed ufnZ if argument not a number will page fault if value cell not resident rounds up } GetFPT: MAR _ Q _ [TT, Rx + 0], c1, at[GetFPT];{not mem ref, byte merge} rhTT _ Rx LRot0, c2; Rx _ Q, rhRx _ MDSTYPEspaceReal, c3; Rx _ Rx LRot8, c1; Rx _ Rx RShift1, SE_1, c2; , c3; MAR _ [rhRx, Rx + 0], c1; Q _ 0FF, c2; Q _ MD and Q, c3; Ybus _ Q xor FloatpType, ZeroBr, c1; Ybus _ Q xor FixpType, ZeroBr, BRANCH[GetnonFpt, $], c2; CANCELBR[$], c3; Map _ [rhTT,TT], L0 _ L0.RedofptGet, c1; Q _ 0FF, L1 _ L1.RestoreTosB2, c2; Rx _ rhRx _ MD, XRefBr, c3; MAR _ [rhRx, TT + 0], BRANCH[FptRemap, $], c1, at[L0.RedofptGet, 10, RMapFixCallerB2]; , c2; TOSH _ MD, c3; MAR _ [rhRx, TT + 1], c1; TT _ LRot1 TOSH, CANCELBR[$, 2], L2Disp, c2; TOS _ MD, RET[FptGetRet], c3; FptRemap: CALL[RLMapFixB2], c2; GetnonFpt: {non-FloatType arg} CANCELBR[ufnX1], c3; { Ybus _ Q xor smallpl, ZeroBr, BRANCH[$, ArgisFixp], c3; Ybus _ Q xor smallneg, ZeroBr, BRANCH[$, ArgisSmallp], c1; TOSH _ 0 - 1, BRANCH[ArgNotNumber, ArgisSmallneg], c2; ArgisFixp: Map _ [rhTT,TT], L0 _ L0.fxptGet, CANCELBR[$], c1; L1 _ L1.tosandtosh, c2; Rx _ rhRx _ MD, XRefBr, c3; MAR _ [rhRx, TT + 0], BRANCH[FxptRemap, $], c1, at[L0.fxptGet, 10, RxMapFixCaller]; , c2; TOSH _ MD, c3; MAR _ [rhRx, TT + 1], c1; CANCELBR[$, 2], c2; TOS _ MD, GOTO[ChipConvFixp], c3; ArgisSmallp: TOSH _ 0, CANCELBR[$], c2; TOS _ TT, GOTO[ChipConvSmallC1], c3; ArgisSmallneg: TOS _ TT, GOTO[ChipConvSmallC1], c3; { to convert using the floating point chip set } { small pos and negs will be directly converted in one step using FLOAT Fixp numbers of less than 25 bits will be directly converted in one step using FLOAT Fixp numbers of more than 24 bits will have their high and low parts converted separately, then 16 is added to the exponent of the high part, and then the two numbers are added } ChipConvSmallC3: , c3; ChipConvSmallC1: {number is in TOSH,,TOS} FloatMode.RN.AI.FAST, FloatULS{flow}, c1; FloatA _ RRot0 TOSH, FLFloatA, GOTO[ccend], c2; ccend: FloatA _ RRot0 TOS, c3; FloatNop, c1; Noop, c2; Noop, c3; Noop, c1; FloatUMS, c2; FloatULS, c3; TOSH _ FloatResult, c1; TOS _ FloatResult, L3Disp, c2; TT _ LRot1 TOSH, RET[FptGetRet], c3; ChipConvFixp: {number is in TOSH,,TOS} {test if number < 24 bits} Ybus _ TOSH and uFF00, ZeroBr, c2; Q _ TOSH + 0FF + 1, BRANCH[$, ChipConvSmallC1], c3; Ybus _ Q and uFF00, ZeroBr, c1; Ybus _ TOSH, NegBr, BRANCH[$, ChipConvSmallC3], c2; {if so then GOTO ChipConvSmall} {else begin} {SIGN _ 0 or -1} BRANCH[pos, neg], c3; pos: uRx{SIGN} _ 0, GOTO[ChipConvLong], c1; neg: uRx{SIGN} _ Rx xor ~Rx, GOTO[ChipConvLong], c1; ChipConvLong: FloatMode.RN.AI.FAST, FloatUMS{pipe}, c2; FloatA _ uRx{SIGN}, FLFloatA, c3; FloatA _ FRot0 TOS, c1; FloatA _ FRot0 Rx, FLFloatA, c2; FloatA _ FRot0 TOSH, c3; FloatA _ 08{FloatPump}, Rx _ 08, c1; FloatA _ FRot0 Rx{FloatPump}, c2; FloatA _ FRot0 Rx{FloatPump}, c3; FloatA _ FRot0 Rx{FloatPump}, c1; FloatA _ FRot0 Rx{FloatPump}, c2; FloatA _ FRot0 Rx{FloatPump}, c3; FloatUMS, Rx _ Rx LRot8, c1; FloatULS, c2; TOSH _ FloatResult, FloatUMS, c3; TOS _ FloatResult, FloatULS, c1; TT _ FloatResult, c2; Q _ FloatResult, c3; Rx _ Rx + Q, c1; FloatMode.RN.AI.FAST, FloatULS{flow}, c2; FloatAB _ FRot0 Rx, c3; FloatAB _ FRot0 TT, c1; FloatA _ FRot0 TOSH, FLPlus, GOTO[ccend], c2; ccend: FloatA _ FRot0 TOS, c3; FloatNop, c1; Noop, c2; Noop, c3; Noop, c1; FloatUMS, c2; FloatULS, c3; TOSH _ FloatResult, c1; TOS _ FloatResult, L3Disp, c2; {end} TT _ LRot1 TOSH, RET[FptGetRet], c3; ArgNotNumber: , c3; } { E N D }