DIRECTORY C2CAddressing, C2CAddressingOps, C2CBasics, C2CDefs, C2CDRunTime, C2CDouble, C2CMode, C2CStateUtils, C2CTarget, C2CEmit, C2CMain, Rope, IntCodeDefs; C2CDoubleImpl: CEDAR PROGRAM IMPORTS C2CAddressing, C2CAddressingOps, C2CBasics, C2CEmit, C2CDRunTime, C2CMain, C2CMode, C2CStateUtils, C2CTarget, Rope EXPORTS C2CDouble = BEGIN OPEN IntCodeDefs, C2CAddressingOps, C2CBasics, C2CDefs, C2CMain, C2CMode; ROPE: TYPE = Rope.ROPE; DTemporary: PROC [] RETURNS [name: ROPE] = { name ¬ C2CStateUtils.DeclareVariable[temporaryDeclarations, C2CTarget.bitsPerDoubleWord, "D"]; }; IsSimpleDFloatArithOp: PROC [node: IntCodeDefs.Node] RETURNS [BOOL¬FALSE] = { IF node.bits#C2CTarget.bitsPerDoubleWord THEN RETURN; WITH node SELECT FROM applyNode: ApplyNode => { IF applyNode.handler#NIL THEN RETURN [FALSE]; WITH applyNode.proc SELECT FROM operNode: OperNode => { WITH operNode.oper SELECT FROM arithOp: ArithOper => IF arithOp.class.precision=C2CTarget.bitsPerDoubleWord AND arithOp.class.kind=real THEN RETURN [TRUE]; ENDCASE => {}; }; ENDCASE => {}; }; ENDCASE => {}; }; LoadAddrRHSD: PROC [node: IntCodeDefs.Node] RETURNS [cc: CodeCont] = { mode: Mode ¬ C2CAddressing.ProposedMode[node: node, lhs: FALSE, wrongSize: FALSE, usedSz: node.bits]; mode ¬ DSetBaseSize[mode, C2CTarget.TemporaryBits[node.bits]]; SELECT GetAMode[mode] FROM plain => { mode ¬ DSetAMode[mode, getAddr]; cc ¬ GenNode[node, mode]; }; getAddr => { cc ¬ GenNode[node, mode]; }; ENDCASE => { sz: INT ¬ C2CTarget.TemporaryBits[node.bits]; tempName: ROPE ¬ C2CStateUtils.DeclareVariable[temporaryDeclarations, sz]; cc ¬ GenNode[node, SetAssUnits[mode, tempName, sz]]; IF cc.ec#NIL THEN CantHappen; cc.ec ¬ C2CEmit.IdentCode[tempName]; cc.ec ¬ C2CEmit.TakeAddr[cc.ec, TRUE]; }; FreeMode[mode]; }; GAppliedDArithOp: PUBLIC PROC [xApp: IntCodeDefs.ApplyNode, arithOp: IntCodeDefs.ArithOper, mode: C2CDefs.Mode] RETURNS [cc: CodeCont] = { cc1, cc2: CodeCont; c: Code; assMode: BOOL ¬ FALSE; name: ROPE; resAddr: Code; kind: IntCodeDefs.ArithClassKind ¬ arithOp.class.kind; SELECT GetAMode[mode] FROM assUnits => { name ¬ GetTemplate[mode]; assMode ¬ TRUE; }; ENDCASE => { name ¬ DTemporary[]; }; resAddr ¬ C2CEmit.Cat["&", name]; IF arithOp.class.precision#C2CTarget.bitsPerDoubleWord THEN ERROR; cc1 ¬ LoadAddrRHSD[xApp.args.first]; SELECT arithOp.select FROM min, max => { copy: ROPE ¬ DTemporary[]; AccessAddr: PROC [arg: Node] RETURNS [Code] = { ccl: CodeCont ¬ LoadAddrRHSD[arg]; cc.sc ¬ C2CEmit.Cat[cc.sc, ccl.sc]; RETURN [ccl.ec]; }; cc ¬ LoadArithNode[xApp.args.first]; cc.sc ¬ C2CEmit.Cat[cc.sc, copy, " = ", cc.ec, ";\n"]; FOR m: NodeList ¬ xApp.args.rest, m.rest WHILE m#NIL DO resPtr: Code ¬ C2CEmit.TakeAddr[C2CEmit.IdentCode[copy], TRUE]; addr: Code ¬ C2CEmit.TakeAddr[C2CEmit.IdentCode[copy], TRUE]; c ¬ AccessAddr[m.first]; SELECT arithOp.select FROM min => c ¬ C2CDRunTime.DMinI[kind, resPtr, addr, c]; max => c ¬ C2CDRunTime.DMaxI[kind, resPtr, addr, c]; ENDCASE => ERROR; cc.sc ¬ C2CEmit.Cat[cc.sc, c, ";\n"]; c ¬ NIL; ENDLOOP; name ¬ copy; assMode ¬ FALSE; }; neg => { c ¬ C2CDRunTime.DNegI[kind, resAddr, cc1.ec]; }; abs => { c ¬ C2CDRunTime.DAbsI[kind, resAddr, cc1.ec]; }; add, sub, mul, div, pow, mod => { cc2 ¬ LoadAddrRHSD[xApp.args.rest.first]; SELECT arithOp.select FROM add => {c ¬ C2CDRunTime.DAddI[kind, resAddr, cc1.ec, cc2.ec]}; sub => {c ¬ C2CDRunTime.DSubI[kind, resAddr, cc1.ec, cc2.ec]}; mul => {c ¬ C2CDRunTime.DMulI[kind, resAddr, cc1.ec, cc2.ec]}; div => {c ¬ C2CDRunTime.DDivI[kind, resAddr, cc1.ec, cc2.ec]}; mod => {c ¬ C2CDRunTime.DModI[kind, resAddr, cc1.ec, cc2.ec]}; pow => { c ¬ C2CDRunTime.DPwrI[kind, resAddr, cc1.ec, cc2.ec]; }; ENDCASE => CaseMissing; }; ENDCASE => NotYetImpl; IF c#NIL THEN c ¬ C2CEmit.Cat[c, ";\n"]; cc.sc ¬ C2CEmit.Cat[cc1.sc, cc.sc, cc2.sc, c]; IF assMode THEN cc.ec ¬ NIL ELSE { cc.ec ¬ C2CEmit.IdentCode[name]; cc ¬ ModizeArithCode[cc, mode, xApp.bits]; }; }; GAppliedDCompareOp: PUBLIC PROC [xApp: IntCodeDefs.ApplyNode, compOp: IntCodeDefs.CompareOper, mode: C2CDefs.Mode] RETURNS [cc: CodeCont] = { cc1, cc2: CodeCont; kind: IntCodeDefs.ArithClassKind ¬ compOp.class.kind; IF compOp.class.precision#C2CTarget.bitsPerDoubleWord THEN NotYetImpl; --ERROR; cc1 ¬ LoadAddrRHSD[xApp.args.first]; cc2 ¬ LoadAddrRHSD[xApp.args.rest.first]; cc.sc ¬ C2CEmit.Cat[cc1.sc, cc2.sc]; SELECT compOp.sense FROM ge => {cc.ec ¬ C2CDRunTime.DGeI[kind, cc1.ec, cc2.ec]}; gt => {cc.ec ¬ C2CDRunTime.DGtI[kind, cc1.ec, cc2.ec]}; eq => {cc.ec ¬ C2CDRunTime.DEqI[kind, cc1.ec, cc2.ec]}; lt => {cc.ec ¬ C2CDRunTime.DGtI[kind, cc2.ec, cc1.ec]}; le => {cc.ec ¬ C2CDRunTime.DGeI[kind, cc2.ec, cc1.ec]}; ne => { cc.ec ¬ C2CEmit.Cat[" ! ", C2CDRunTime.DEqI[kind, cc1.ec, cc2.ec]]; cc.ec ¬ C2CEmit.SetPrecedence[cc.ec, unaryPrecedence]; }; ENDCASE => CaseMissing; }; GAppliedDConvertOp: PUBLIC PROC [xApp: IntCodeDefs.ApplyNode, convertOp: IntCodeDefs.ConvertOper, mode: C2CDefs.Mode] RETURNS [cc: CodeCont] = { template, key: ROPE; assMode: BOOL ¬ FALSE; IF convertOp.to.precision { SELECT convertOp.to.kind FROM real => cc.ec ¬ C2CDRunTime.FloatDRealI[cc.ec]; ENDCASE => CantHappen; }; signed => { SELECT convertOp.to.kind FROM signed => cc.ec ¬ C2CDRunTime.IntDIntI[cc.ec]; unsigned => cc.ec ¬ C2CDRunTime.CardDIntI[cc.ec]; real => cc.ec ¬ C2CDRunTime.FloatDIntI[cc.ec]; ENDCASE => CantHappen; }; unsigned => { SELECT convertOp.to.kind FROM signed => cc.ec ¬ C2CDRunTime.IntDCardI[cc.ec]; unsigned => cc.ec ¬ C2CDRunTime.CardDCardI[cc.ec]; real => cc.ec ¬ C2CDRunTime.FloatDCardI[cc.ec]; ENDCASE => CantHappen; }; ENDCASE => CantHappen; RETURN; }; IF convertOp.to.precision#C2CTarget.bitsPerDoubleWord THEN CantHappen; SELECT GetAMode[mode] FROM assUnits => { template ¬ GetTemplate[mode]; assMode ¬ TRUE; }; ENDCASE => { template ¬ DTemporary[]; }; IF convertOp.from.precision<=C2CTarget.bitsPerWord THEN { IF convertOp.from.precision {}; ENDCASE => CantHappenCedar; }; cc ¬ LoadArithNode[node: xApp.args.first]; cc.ec ¬ C2CEmit.MinPrecedence[cc.ec, primaryPrecedence]; SELECT convertOp.to.kind FROM signed => SELECT convertOp.from.kind FROM signed => key ¬ "DIntInt"; unsigned => key ¬ "DIntCard"; ENDCASE => CantHappenCedar; unsigned => SELECT convertOp.from.kind FROM signed => key ¬ "DCardInt"; unsigned => key ¬ "DCardCard"; ENDCASE => CantHappenCedar; real => { SELECT convertOp.from.kind FROM signed => key ¬ "DFloatInt"; unsigned => key ¬ "DFloatCard"; real => key ¬ "DFloatReal"; ENDCASE => CantHappenCedar; }; ENDCASE => CantHappenCedar; } ELSE IF convertOp.from.precision=C2CTarget.bitsPerDoubleWord THEN { cc ¬ LoadAddrRHSD[xApp.args.first]; cc.ec ¬ C2CEmit.MinPrecedence[cc.ec, primaryPrecedence]; SELECT convertOp.to.kind FROM real => { SELECT convertOp.from.kind FROM signed => key ¬ "DFloatDIntI"; unsigned => key ¬ "DFloatDCardI"; ENDCASE => CantHappen; }; signed => SELECT convertOp.from.kind FROM unsigned => key ¬ "DIntDCardI"; ENDCASE => CantHappen; unsigned => SELECT convertOp.from.kind FROM signed => key ¬ "DCardDIntI"; ENDCASE => CantHappen; ENDCASE => CantHappen; } ELSE CantHappenCedar; IF key=NIL THEN CantHappen; key ¬ Rope.Concat[C2CTarget.runtimePrefix, key]; cc.ec ¬ C2CEmit.CatCall[key, "&", template, ", ", cc.ec]; SELECT GetAMode[mode] FROM assUnits => { cc.sc ¬ C2CEmit.Cat[cc.sc, cc.ec, ";\n"]; cc.ec ¬ NIL; }; ENDCASE => { cc.sc ¬ C2CEmit.Cat[cc.sc, cc.ec, ";\n"]; cc.ec ¬ C2CEmit.IdentCode[template]; cc ¬ ModizeArithCode[cc, mode, convertOp.to.precision]; }; }; END. D C2CDoubleImpl.mesa Copyright Σ 1989, 1990, 1991 by Xerox Corporation. All rights reserved. Christian Jacobi, March 15, 1989 11:41:46 am PST Christian Jacobi, October 5, 1990 1:49:01 pm PDT --D: does not worry about not generating statement code plain => { cc _ GenNode[node, mode]; cc.ec _ C2CEmit.TakeAddr[cc.ec, TRUE]; }; --never needs temporary because all double expression results in variables --we could improve this by not simply using a linear list --no mixed mode power operation: base and exponent of same type --from word to double word --from double to double Κ –(cedarcode) style•NewlineDelimiter ™šœ™Icodešœ Οeœ=™HKšœ0™0Kšœ0™0—šΟk ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ ˜ K˜—šΟn œžœž˜Kšžœs˜zKšžœ ˜—šž˜KšžœE˜I—Kšžœžœžœ˜K˜K˜šŸ œžœžœžœ˜,Kšœ^˜^Kšœ˜—K˜šŸœžœžœž œ˜MKšžœ'žœžœ˜5šžœžœž˜šœ˜Kš žœžœžœžœžœ˜-šžœžœž˜šœ˜šžœžœž˜Kš œžœ5žœžœžœžœ˜|Kšžœ˜—Kšœ˜—Kšžœ˜—K˜—Kšžœ˜—K˜—K˜šŸ œžœžœ˜FKšΟc7™7Kšœ9žœ žœ˜eKšœ>˜>šžœž˜šœ ™ Kšœ™Kšœ žœ™&K™—šœ ˜ Kšœ ˜ Kšœ˜K˜—šœ ˜ Kšœ˜Kšœ˜—šžœ˜ Kšœžœ&˜-Kšœ žœ<˜JKšœ4˜4Kšžœžœžœ ˜Kšœ$˜$Kšœ žœ˜&Kšœ˜——Kšœ˜Kšœ˜—K˜K˜šŸœžœžœSžœ˜ŠKšœ&žœžœžœ˜NKšœ6˜6šžœž˜šœ ˜ Kšœ$žœ˜)Kšœ˜—šžœ˜ Kšœ˜Kšœ˜——Kšœ!˜!Kšžœ5žœžœ˜BKšœ$˜$šžœž˜šœ ˜ Kšœžœ˜šŸ œžœ žœ ˜/Kš J™JKšœ"˜"Kšœ$˜$Kšžœ ˜K˜—Kšœ$˜$Kšœ6˜6šžœ&žœžœž˜7Kš 9™9Kšœ9žœ˜?Kšœ7žœ˜=Kšœ˜šžœž˜Kšœ4˜4Kšœ4˜4Kšžœžœ˜—Kšœ&˜&Kšœžœ˜Kšžœ˜—Kšœ ˜ Kšœ žœ˜Kšœ˜—šœ˜Kšœ-˜-K˜—šœ˜Kšœ-˜-K˜—šœ!˜!Kšœ)˜)šžœž˜Kšœ>˜>Kšœ>˜>Kšœ>˜>Kšœ>˜>Kšœ>˜>šœ˜Kš ?™?Kšœ5˜5Kšœ˜—Kšžœ˜—K˜—Kšžœ˜—Kšžœžœžœ˜(Kšœ.˜.šžœ ˜ Kšžœ žœ˜šžœ˜Kšœ ˜ Kšœ*˜*K˜——Kšœ˜K˜—šŸœžœžœTžœ˜Kšœ˜Kšœ5˜5Kšžœ4žœ  ˜OKšœ$˜$Kšœ)˜)Kšœ$˜$šžœž˜Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7Kšœ7˜7šœ˜KšœD˜DKšœ6˜6Kšœ˜—Kšžœ˜—K˜—K˜šŸΠlnŸ œž œWžœ˜Kšœžœž˜+šžœ1žœ˜9Kšžœ.žœ6žœ ˜xKšœ#˜#šžœž˜šœ ˜ šžœž˜Kšœ/˜/Kšžœ˜—Kšœ˜—šœ ˜ šžœž˜Kšœ.˜.Kšœ1˜1Kšœ.˜.Kšžœ˜—Kšœ˜—šœ ˜ šžœž˜Kšœ/˜/Kšœ2˜2Kšœ/˜/Kšžœ˜—Kšœ˜—Kšžœ˜—Kšžœ˜K˜—Kšžœ4žœ ˜Fšžœž˜šœ ˜ Kšœ(žœ˜-Kšœ˜—šžœ˜ Kšœ˜Kšœ˜——šžœ1žœ˜9šžœ0žœ˜8šžœž˜Kšœ˜Kšžœ˜—K˜—Kšœ™Kšœ*˜*Kšœ8˜8šžœž˜šœ ˜ šžœž˜Kšœ˜Kšœ˜Kšžœ˜——šœ ˜ šžœž˜Kšœ˜Kšœ˜Kšžœ˜——šœ ˜ šžœž˜Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—K˜—Kšžœ˜—K˜—šžœžœ6žœ˜CKš ™Kšœ#˜#Kšœ8˜8šžœž˜šœ ˜ šžœž˜Kšœ˜Kšœ!˜!Kšžœ˜—K˜—šœ ˜ šžœž˜Kšœ˜Kšžœ˜——šœ ˜ šžœž˜Kšœ˜Kšžœ˜——Kšžœ˜—Kšœ˜—Kšžœ˜Kšžœžœžœ ˜Kšœ0˜0Kšœ9˜9šžœž˜šœ ˜ Kšœ)˜)Kšœžœ˜ Kšœ˜—šžœ˜ Kšœ)˜)Kšœ$˜$Kšœ7˜7K˜——K˜K˜—Iimpšžœ˜K˜—…—F*