Machine-Independent MDL for TOPS-20 and VAX.
[pdp10-muddle.git] / mim / development / mim / vaxc / callrte.mud
diff --git a/mim/development/mim/vaxc/callrte.mud b/mim/development/mim/vaxc/callrte.mud
new file mode 100644 (file)
index 0000000..4cb4e23
--- /dev/null
@@ -0,0 +1,374 @@
+<USE "CHANNEL-TYPE">
+
+<DEFINE FIND-CALL (ATM LIST)
+  #DECL ((ATM) ATOM (LIST) <LIST [REST ATOM]>)
+  <REPEAT ()
+    <COND (<EMPTY? .LIST> <RETURN <>>)>
+    <COND (<SAME-NAME? .ATM <1 .LIST>> <RETURN T>)>
+    <SET LIST <REST .LIST>>>>
+
+<DEFINE SAME-NAME? (X Y "AUX" S1 S2)
+  #DECL ((X Y) ATOM (S1 S2) STRING)
+  <COND (<NOT ,INT-MODE>
+        <==? .X .Y>)
+       (T
+        <SET S1 <SPNAME .X>>
+        <SET S2 <SPNAME .Y>>
+        <OR <==? .X .Y>
+            <AND <G? <LENGTH .S1> 2>
+                 <==? <1 .S1> !\T>
+                 <==? <2 .S1> !\$>
+                 <=? <REST .S1 2> .S2>>
+            <AND <G? <LENGTH .S2> 2>
+                 <==? <1 .S2> !\T>
+                 <==? <2 .S2> !\$>
+                 <=? <REST .S2 2> .S1>>>)>>
+
+<DEFINE INIT-CALL-DISPATCH () 
+       <SETG RTE-DISP-TABLE <IVECTOR ,RTE-DISPATCH-TABLE-SIZE <>>>
+       <SETG RTE-PTR ,DISPATCH-TABLE-START>>
+
+<GDECL (RTE-PTR) FIX>
+
+<DEFINE CREATE-CALL-DESC (NAME FLUSH? RESULT?
+                         "TUPLE" ARGS
+                         "AUX" ANAME (OFF ,RTE-PTR))
+       #DECL ((NAME) STRING (OFF) FIX (FLUSH?) BOOLEAN
+              (RESULT?) <OR FALSE DATUM>)
+       <SET ANAME
+            <OR <LOOKUP .NAME ,MIMOP-OBLIST> <INSERT .NAME ,MIMOP-OBLIST>>>
+       <PUT ,RTE-DISP-TABLE <+ </ .OFF 4> 1> .ANAME>
+       <SETG .ANAME
+             <CHTYPE <VECTOR .OFF .ANAME <VECTOR !.ARGS> .RESULT? .FLUSH?>
+                     CALL-DESCRIPTOR>>
+       <SETG RTE-PTR <+ ,RTE-PTR 4>>>
+
+<DEFINE CREATE-DATUM (TYP TAC VAC) 
+       #DECL ((TYP TAC VAC) <OR FALSE ATOM>)
+       <CHTYPE <VECTOR .TYP .TAC .VAC> DATUM>>
+
+<DEFINE RTE-ARGS (KIND TAC VAC) 
+       #DECL ((KIND VAC) ATOM (TAC) <OR FALSE ATOM>)
+       <COND (<NOT <MEMQ .KIND '[VALUE TYPE-VALUE-PAIR COUNT-VALUE-PAIR]>>
+              <ERROR "BAD-AC-LDESC" CREATE-AC-LDESC>)>
+       <COND (<AND .TAC <OR <NOT <GASSIGNED? .TAC>> <NOT <TYPE? ,.TAC AC>>>>
+              <ERROR "BAD AC" CREATE-AC-LDESC>)>
+       <COND (<OR <NOT <GASSIGNED? .VAC>> <NOT <TYPE? ,.VAC AC>>>
+              <ERROR "BAD AC" CREATE-AC-LDESC>)>
+       <CHTYPE <VECTOR .KIND .TAC .VAC> AC-LDESC>>
+
+<SETG SAME-STACK <>>
+
+<DEFINE CALL-RTE (CDESC INST DEST HINT "TUPLE" ARGS "AUX" JAC JADDR) 
+       #DECL ((CDESC) CALL-DESCRIPTOR (INST) ATOM
+              (DEST) <OR ATOM FALSE VARTBL> (HINT) <OR FALSE HINT ATOM>)
+       <COND (<AND <TYPE? .DEST VARTBL>
+                   <NOT <MEMQ .DEST .ARGS>>
+                   <OR <VAR-VALUE-IN-AC? .DEST>
+                       <VAR-TYPE-IN-AC? .DEST>
+                       <VAR-COUNT-IN-AC? .DEST>
+                       <VAR-TYPE-WORD-IN-AC? .DEST>>>
+              <DEAD-VAR .DEST>)>
+       <MAPR <>
+             <FUNCTION (SARGS ADS) 
+                     <PROCESS-RTE-ARG <1 .SARGS>
+                                      <1 .ADS>
+                                      .SARGS
+                                      .ARGS
+                                      <CD-ARGS .CDESC>>>
+             .ARGS
+             <CD-ARGS .CDESC>>
+       <FREE-RESULT-ACS <CD-ARGS .CDESC> <CD-RESULT .CDESC>>
+       <COND (<CD-FLUSH?-ACS .CDESC> <FLUSH-ALL-ACS>)>
+       <SET JADDR <CD-DISP-OFFSET .CDESC>>
+       <COND (<==? .INST CALL> <EMIT ,INST-JSB <MA-ABS .JADDR>>)
+             (<==? .INST JUMP> <EMIT ,INST-JMP <MA-ABS .JADDR>>)>
+       <SET-RTE-RESULT <CD-RESULT .CDESC> .DEST .HINT>
+       <CLEAR-STATUS>
+       NORMAL>
+
+<DEFINE FREE-RESULT-ACS (ARGS RESULT "AUX" VAC) 
+       #DECL ((ARGS) <VECTOR [REST ARG-DESCRIPTOR]> (RESULT) <OR FALSE
+                                                                 DATUM>)
+       <COND (<TYPE? .RESULT DATUM>
+              <COND (<SET VAC <DATUM-TAC .RESULT>>
+                     <OR <CALLUSE? .VAC .ARGS> <GET-AC ,.VAC T>>)>
+              <COND (<SET VAC <DATUM-VAC .RESULT>>
+                     <OR <CALLUSE? .VAC .ARGS> <GET-AC ,.VAC T>>)>)>
+       T>
+
+<DEFINE CALLUSE? (VAC ARGS "AUX" (RES <>)) 
+       #DECL ((VAC) ATOM (ARGS) <VECTOR [REST ARG-DESCRIPTOR]>)
+       <MAPF <>
+             <FCN (ARG)
+                  <COND (<AND <TYPE? .ARG AC-LDESC>
+                              <OR <==? <AC-LDESC-TAC .ARG> .VAC>
+                                  <==? <AC-LDESC-VAC .ARG> .VAC>>>
+                         <SET RES T>
+                         <MAPLEAVE>)>>
+             .ARGS>
+       .RES>
+
+<DEFINE SET-RTE-RESULT (RDAT DEST HINT) 
+       #DECL ((DEST) <OR FALSE ATOM VARTBL> (RDAT) <OR FALSE DATUM>
+              (HINT) <OR FALSE HINT ATOM>)
+       <COND (<AND .RDAT .DEST>
+              <COND (<DATUM-TAC .RDAT>
+                     <DEST-PAIR ,<DATUM-VAC .RDAT> ,<DATUM-TAC .RDAT> .DEST>)
+                    (<DATUM-TYPE .RDAT>
+                     <DEST-DECL ,<DATUM-VAC .RDAT> .DEST <DATUM-TYPE .RDAT>>)
+                    (<ERROR "BAD DATUM" SET-RTE-RESULT>)>
+              <PROCESS-DESTINATION-HINT .HINT .DEST>)>>
+
+<NEWTYPE ARG-DONE FIX>
+
+<DEFINE PROCESS-RTE-ARG PRA (ARG AD SARGS ARGS ADS "AUX" VAC TAC) 
+   #DECL ((ARGS) TUPLE (ADS) VECTOR (ARG) ANY (AD) <OR AC-LDESC ATOM>)
+   <COND
+    (<NOT <TYPE? .ARG ARG-DONE>>
+     <COND (<==? .AD STACK>
+           <COND (<TYPE? .ARG VARTBL> <PUSH-VAR .ARG>)
+                 (ELSE <PUSH-CONSTANT .ARG>)>)
+          (<AND <TYPE? .AD AC-LDESC>
+                <==? <AC-LDESC-KIND .AD> TYPE-VALUE-PAIR>
+                <==? <NEXT-AC <SET TAC ,<AC-LDESC-TAC .AD>>>
+                     <SET VAC ,<AC-LDESC-VAC .AD>>>>
+           <CHECK-AC-USE .ARGS .SARGS .ADS .ARG .TAC .VAC>
+           <COND (<TYPE? <SET ARG <1 .SARGS>> ARG-DONE> <RETURN T .PRA>)>
+           <LOAD-AC-PAIR .ARG <> ,<AC-LDESC-TAC .AD>>
+           <PROTECT-USE .TAC>
+           <PROTECT-USE .VAC>)
+          (<TYPE? .AD AC-LDESC>
+           <CHECK-AC-USE .ARGS
+                         .SARGS
+                         .ADS
+                         .ARG
+                         <AC-LDESC-TAC .AD>
+                         <AC-LDESC-VAC .AD>>
+           <COND (<TYPE? <SET ARG <1 .SARGS>> ARG-DONE> <RETURN T .PRA>)>
+           <COND (<TYPE? .ARG VARTBL>
+                  <SET VAC
+                       <LOAD-VAR .ARG
+                                 <COND (<==? <AC-LDESC-KIND .AD>
+                                             TYPE-VALUE-PAIR>
+                                        VALUE)
+                                       (ELSE JUST-VALUE)>
+                                 T
+                                 ,<AC-LDESC-VAC .AD>>>
+                  <PROTECT-USE .VAC>)
+                 (ELSE
+                  <SET VAC <GET-AC ,<AC-LDESC-VAC .AD> T>>
+                  <PROTECT-USE .VAC>
+                  <MOVE-VALUE .ARG .VAC>
+                  <MUNG-AC .VAC>)>
+           <COND (<TYPE? .ARG VARTBL>
+                  <COND (<==? <AC-LDESC-KIND .AD> TYPE-VALUE-PAIR>
+                         <SET VAC
+                              <LOAD-VAR .ARG TYPE-WORD T ,<AC-LDESC-TAC
+                                                           .AD>>>
+                         <PROTECT-USE .VAC>)
+                        (<==? <AC-LDESC-KIND .AD> COUNT-VALUE-PAIR>
+                         <SET VAC <LOAD-VAR .ARG COUNT T ,<AC-LDESC-TAC
+                                                           .AD>>>
+                         <PROTECT-USE .VAC>)>)
+                 (ELSE
+                  <COND (<==? <AC-LDESC-KIND .AD> TYPE-VALUE-PAIR>
+                         <SET VAC <GET-AC ,<AC-LDESC-TAC .AD> T>>
+                         <PROTECT-USE .VAC>
+                         <MOVE-TYPE .ARG <MA-REG .VAC>>
+                         <MUNG-AC .VAC>)
+                        (<==? <AC-LDESC-KIND .AD> COUNT-VALUE-PAIR>
+                         <SET VAC <GET-AC ,<AC-LDESC-TAC .AD> T>>
+                         <PROTECT-USE .VAC>
+                         <LOAD-CONSTANT .VAC <LENGTH .ARG>>
+                         <MUNG-AC .VAC>)>)>)>
+     <1 .SARGS <CHTYPE 0 ARG-DONE>>)>>
+
+<DEFINE CHECK-AC-USE (ARGS SARGS ADS ARG
+                     "TUPLE" ACS)
+   #DECL ((SARGS ARGS) TUPLE (ADS) VECTOR (ACS) TUPLE)
+   <MAPF <>
+    <FUNCTION (AC) 
+       #DECL ((AC) <OR FALSE AC ATOM>)
+       <COND (<TYPE? .AC ATOM> <SET AC ,.AC>)>
+       <COND
+       (.AC
+        <MAPF <>
+         <FUNCTION (LINKVAR "AUX" TV (VAR <LINKVAR-VAR .LINKVAR>)) 
+            <COND
+             (<OR <AND <==? .AC <LINKVAR-VALUE-AC .LINKVAR>>
+                       <NOT <LINKVAR-VALUE-STORED .LINKVAR>>>
+                  <AND <==? .AC <LINKVAR-TYPE-AC .LINKVAR>>
+                       <NOT <LINKVAR-TYPE-STORED .LINKVAR>>>
+                  <AND <==? .AC <LINKVAR-COUNT-AC .LINKVAR>>
+                       <NOT <LINKVAR-COUNT-STORED .LINKVAR>>>
+                  <AND <==? .AC <LINKVAR-TYPE-WORD-AC .LINKVAR>>
+                       <NOT <LINKVAR-TYPE-STORED .LINKVAR>>>>
+                                                 ;"Might be something in here"
+              <REPEAT ((TV .ARGS))
+                <COND
+                 (<SET TV <MEMQ .VAR .TV>>
+                                      ;"It's OK if current arg is in right AC"
+                  <COND
+                   (<==? .TV .SARGS>
+                    <SET TV <REST .TV>>)
+                   (<L? <LENGTH .TV> <LENGTH .SARGS>>
+                    <PROCESS-RTE-ARG
+                     <1 .TV>
+                     <NTH .ADS <+ 1 <- <LENGTH .ADS> <LENGTH .TV>>>>
+                     .TV
+                     .ARGS
+                     .ADS>)
+                   (T                                         ;"Loop detected"
+                    <ISTORE-VAR .LINKVAR <> T>
+                    ; "Can't use will-die? here"
+                    <RETURN>)>)
+                 (<RETURN>)>>)>>
+         <AC-VARS .AC>>)>>
+    .ACS>>
+
+<DEFINE RESET-FRAME-LABEL-TABLE () <SETG FRAME-LABEL-TABLE ()>>
+
+<DEFINE SFRAME-GEN ("OPTIONAL" (NAME <>))
+       <FRAME-GEN .NAME T>>
+
+<DEFINE FRAME-GEN ("OPTIONAL" (NAME <>) (SEG <>) "AUX" TLAB ELAB VAC) 
+       #DECL ((NAME) <OR FALSE ATOM>)
+       <COND (<AND ,GLUE .NAME <QUICK-CALL? .NAME>>
+              <EMIT-PUSH <TYPE-CODE <COND (.SEG QSFRAME)
+                                          (ELSE QFRAME)>> WORD>
+              <SET TLAB <MAKE-LABEL>>
+              <SETG FRAME-LABEL-TABLE (.TLAB !,FRAME-LABEL-TABLE)>
+              <EMIT-PUSH-LABEL .TLAB>
+              <EMIT-PUSH <MA-REG ,AC-F> LONG>
+              <SET ELAB <MAKE-LABEL>>
+              <COND (<AND ,MAKTUP-FLAG <0? ,ICALL-LEVEL>>
+                     <SET VAC <GET-AC PREF-VAL T>>
+                     <EMIT-MOVE <MA-BD ,AC-F -4> <MA-REG .VAC> LONG>
+                     <EMIT ,INST-TSTB <MA-BD .VAC -1>>
+                     <GEN-BRANCH ,INST-BLSS .ELAB <>>
+                     <EMIT-MOVE <MA-BD .VAC -4> <MA-REG .VAC> LONG>
+                     <EMIT-LABEL .ELAB <>>
+                     <EMIT-PUSH <MA-REG .VAC> LONG>)
+                    (ELSE
+                     <EMIT-PUSH <MA-BD ,AC-F -4> LONG>
+                     <GEN-BRANCH ,INST-BGEQ .ELAB <>>
+                     <EMIT-MOVE <MA-REG ,AC-F> <MA-BD ,AC-TP -4> LONG>
+                     <EMIT-LABEL .ELAB <>>)>)
+             (<CALL-RTE <COND (.SEG ,ISFRAME!-MIMOP)
+                              (ELSE ,IFRAME!-MIMOP)> CALL <> <>>)>
+       NORMAL>
+
+<DEFINE SCALL-GEN (NAME NARGS RES DIR TAG COUNT "OPTIONAL" (HINT <>))
+       <CCALL-GEN .NAME .NARGS .RES .TAG .COUNT .HINT>>
+
+<DEFINE CALL-GEN (NAME NARGS "OPTIONAL" (RES <>) (HINT <>))
+       <CCALL-GEN .NAME .NARGS .RES <> <> .HINT>>
+
+<DEFINE CCALL-GEN (NAME NARGS RES TAG COUNT HINT "AUX" (TLAB <MAKE-LABEL>)) 
+       #DECL ((NAME) <OR ATOM VARTBL> (NARGS) <OR FIX VARTBL>
+              (RES) <OR ATOM VARTBL FALSE> (HINT) <OR FALSE ATOM>)
+       <COND (<AND ,GLUE <TYPE? .NAME ATOM> <QUICK-CALL? .NAME>>
+              <COND (<TYPE? .NARGS FIX>
+                     <FLUSH-ALL-ACS>
+                     <EMIT ,INST-MOVAL
+                           <MA-DISP ,AC-TP <* -8 .NARGS>>
+                           <MA-REG ,AC-F>>
+                     <LOAD-CONSTANT ,AC-0 .NARGS>
+                     <EMIT-CALL .NAME .NARGS>)
+                    (ELSE
+                     <LOAD-VAR .NARGS VALUE T ,AC-0>
+                     <MAPF <>
+                       <FUNCTION (X) <COND (<N==? .X ,AC-0>
+                                            <MUNG-AC .X>)>>
+                       ,ALL-ACS>
+                     <EMIT ,INST-ASHL
+                           <MA-IMM 3>
+                           <MA-REG ,AC-0>
+                           <MA-REG ,AC-1>>
+                     <EMIT ,INST-SUBL3
+                           <MA-REG ,AC-1>
+                           <MA-REG ,AC-TP>
+                           <MA-REG ,AC-F>>
+                     <EMIT-CALL .NAME -1>)>
+              <EMIT-LABEL <1 ,FRAME-LABEL-TABLE> <>>
+              <SETG FRAME-LABEL-TABLE <REST ,FRAME-LABEL-TABLE>>
+              <COND (.TAG
+                     <EMIT-BRANCH ,INST-BRB .TLAB <> 0 <> T>
+                     <EMIT ,INST-ADDL2 <MA-REG ,AC-1> <ADDR-VAR-VALUE .COUNT>>
+                     <GEN-BRANCH ,INST-BRB .TAG <>>)>
+              <EMIT-LABEL .TLAB <>>
+              <SET-RTE-RESULT <CD-RESULT ,MCALL!-MIMOP> .RES .HINT>)
+             (<CALL-RTE ,MCALL!-MIMOP
+                        CALL
+                        <COND (.TAG <>) (ELSE .RES)>
+                        .HINT
+                        .NARGS
+                        .NAME>
+              <COND (.TAG
+                     <EMIT-BRANCH ,INST-BRB .TLAB <> 0 <> T>
+                     <EMIT ,INST-ADDL2 <MA-REG ,AC-1> <ADDR-VAR-VALUE .COUNT>>
+                     <GEN-BRANCH ,INST-BRB .TAG UNCONDITIONAL-BRANCH>
+                     <EMIT-LABEL .TLAB <>>
+                     <SET-RTE-RESULT <CD-RESULT ,MCALL!-MIMOP> .RES .HINT>)>)>
+       NORMAL>
+
+<DEFINE CALL-STACK-FUNCTION (ARGS CALLR TYP "TUPLE" CARGS "AUX" DEST (CNT 0)) 
+       #DECL ((ARGS) TUPLE (CALLR) CALL-DESCRIPTOR (TYP) <OR ATOM FALSE>)
+       <MAPR <>
+             <FCN (FARGS "AUX" (ARG <1 .FARGS>))
+                  <COND (<OR <==? .ARG STACK> <TYPE? .ARG VARTBL>>
+                         <SET DEST .ARG>)>
+                  <COND (<OR <1? <LENGTH .FARGS>> <TYPE? <2 .FARGS> LIST>>
+                         <MAPLEAVE>)
+                        (ELSE <PUSH-GEN .ARG> <SET CNT <+ .CNT 1>>)>>
+             .ARGS>
+       <CALL-RTE .CALLR CALL .DEST .TYP !.CARGS .CNT>
+       NORMAL>
+
+<DEFINE QUICK-CALL? (NAME)
+       #DECL ((NAME) ATOM)
+       <FIND-CALL .NAME ,GLUE-FCNS>>
+
+<DEFINE CHANNEL-OP-GEN (TYPE OPER CHANNEL "TUPLE" ARGS
+                       "AUX" (RES ,HAS-RESULT) FROB)
+  #DECL ((TYPE OPER) ATOM (CHANNEL) VARTBL)
+  <COND (<AND ,GLUE
+             <SET FROB <CT-QUERY .TYPE .OPER>>
+             <QUICK-CALL? .FROB>>
+        ; "If we know what we're calling, and are compiling it, we'll make
+           a glued call"
+        <FRAME-GEN .FROB>)
+       (T
+        <SET FROB <>>
+        <CALL-RTE ,IFRAME!-MIMOP CALL <> <>>)>
+  <PUSH-VAR .CHANNEL>
+  ; "Push channel"
+  <PUSH-CONSTANT .OPER>
+  ; "Push operation"
+  <MAPF <>
+    <FUNCTION (ARG)
+      <COND (<TYPE? .ARG VARTBL>
+            <PUSH-VAR .ARG>)
+           (T
+            <PUSH-CONSTANT .ARG>)>>
+    .ARGS>
+  ; "Push args"
+  <FLUSH-ALL-ACS>
+  <COND (.FROB
+        ; "If glued call, go through normal code"
+        <CALL-GEN .FROB <+ 2 <LENGTH .ARGS>> .RES>)
+       (T
+        <EMIT-MOVE
+         <MA-DEF-DISP ,AC-M <+ <ADD-MVEC <CHTYPE (.TYPE .OPER) XCHANNEL-OP>>
+                               4>>
+         <MA-REG ,AC-0> DOUBLE>
+        ; "Get atom to call (1st element of funny list stored in mvector)"
+        <EMIT-MOVE <MA-IMM <+ 2 <LENGTH .ARGS>>> <MA-REG ,AC-0> LONG>
+        ; "Number of args"
+        <EMIT ,INST-JSB <MA-ABS <CD-DISP-OFFSET ,MCALL!-MIMOP>>>
+        ; "Do call"
+        <SET-RTE-RESULT <CD-RESULT ,MCALL!-MIMOP> .RES <>>
+        ; "Hack result"
+        <CLEAR-STATUS>
+        NORMAL)>>
\ No newline at end of file