1 //  ******************************************************
  2 //  *                                                    *
  3 //  *                                                    *
  4 //  * Copyright (c) 1972 by Massachusetts Institute of   *
  5 //  * Technology and Honeywell Information Systems, Inc. *
  6 //  *                                                    *
  7 //  *                                                    *
  8 //  ******************************************************
  9 
 10 //  Canned code sequences (call/save/return, etc.).
 11 //  Modified March 1982 by C. Hornig to set stack_frame.next_sp properly.
 12 //  Modified on 06/14/74 at 01:13:39 by R F Mabee.
 13 //  Converted for 6180 operation and installed in Version 3.4, R F Mabee.
 14 //  First installed in Version 2.7 by R F Mabee.
 15 
 16 //  Copyright (c) 1974 by Massachusetts Institute of Technology and Honeywell Information Systems, Inc.
 17 
 18 //  General permission is granted to copy and use this program, but not to sell it, provided that the above
 19 //  copyright statement is given.  Contact Information Processing Services, MIT, for further information.
 20 //  Please contact R F Mabee at MIT for information on this program and versions for other machines.
 21 
 22 get "bcpl_cg_head"
 23 get "bcpl_opcodes"
 24 
 25 let NewSSP (S) be
 26           if S > MaxSSP do MaxSSP := S
 27 
 28 and Compentry (L, ID, FunctSw, MainSw) be
 29      $(   Jumpsw := false
 30           MaxSSP, LabMaxSSP := 0, Nextparam ()
 31           MaxArgOffset, LabMaxArg := 0, Nextparam ()
 32           let v = vec Vmax
 33           Concatenate (v, Vmax, "*fBegin text of ", ID)
 34           SectionHeader (StoreString (v))
 35           Outstring (ID)
 36           if MainSw do                  //  Also need def ptr before entry.
 37                $(   let M = Nextparam ()
 38                     MainEntriesList := List4 (L, M, ID, MainEntriesList)
 39                     Reloc, Param, Comment := RelDef lshift Left, M, "relative pointer to definition for entry"
 40                     OutData (0)
 41                $)
 42           Complab (L)
 43           Comment := "set lp to linkage section"
 44           test Machine = 645
 45           then $(   if GetLpLabel = 0 do GetLpLabel := Nextparam ()
 46                     Outop2 (Tsx0, GetLpLabel)
 47                $)
 48           or   $(   Outop3 (Epaq, 0, 0)
 49                     Outop3 (Lprplp, 22, Sb | StarThenReg | Au)
 50                $)
 51 
 52           if MainSw do
 53                $(   if EntryLabel = 0 do EntryLabel := Nextparam ()
 54                     Comment := "execute Multics save"
 55                     Outop2 (Tsx0, EntryLabel)
 56                $)
 57           Outop4 (Adlx1, 0, Bp, "BCPL save")
 58           test Machine = 645
 59           then $(   Outop3 (Stpbp, 0, StackRefTag)
 60                     Outop3 (Stplp, 2, StackRefTag)
 61                $)
 62           or   $(   Outop3 (Sprpbp, 0, StackRefTag)
 63                     Outop3 (Sprplp, 1, StackRefTag)
 64                $)
 65           Address, Tag, Param := 15, StackRefTag, LabMaxArg
 66           Outop (Eax0)
 67           Outop3 (Anx0, Mod16, Du)
 68           unless Machine = 645
 69                do Outop3 (Stx0, 21, Sb)
 70           Comment := "end of save sequence*n"
 71           Outop3 (Stx0, 19, Sp)
 72      $)
 73 
 74 and Compreturn (Desc) be
 75      $(   unless Desc = 0 do
 76                $(   LoadRegister (Desc, Qr)
 77                     DisclaimRegister (Desc)
 78                $)
 79           test Machine = 645
 80           then Outop4 (Eapbp, 0, StackRefTag | Star, "bcpl return")
 81           or Outop4 (Lprpbp, 0, StackRefTag, "bcpl return")
 82           Outop3 (Sblx1, 0, Bp)
 83           test Machine = 645
 84           then Outop3 (Eaplp, 2, StackRefTag | Star)
 85           or Outop3 (Lprplp, 1, StackRefTag)
 86           Outop4 (Tra, 1, Bp, "end of return sequence")
 87           MaxSSP := MaxSSP + SaveSpaceSize + 1 & Even
 88           Equate (LabMaxSSP, MaxSSP)
 89           Equate (LabMaxArg, (MaxSSP > 256 -> MaxSSP, 256) + MaxArgOffset)                //  Don't reduce caller's sb|21.
 90           OutLiterals ()
 91           Jumpsw := true
 92      $)
 93 and Equate (L, n) be
 94      $(   DefineLab (L, n)
 95           if Listing do Format (OUTPUT, "*tequ*tL^d,^d*n", L, n)
 96      $)
 97 
 98 and CreateArglist (Nargs) be
 99           ArgCount, ArgLen := Nargs, Nargs + SaveSpaceSize
100 and StoreArg (i, Desc) be
101      $(   let To = list LV_ARG_OUT, i, 0
102           Store (Desc, To)
103           DisclaimRegister (Desc)
104      $)
105 and Compfnap (Result, F) be
106      $(   SetupAddr (F)
107           if F!0 = RTDEF_S do Address := Address + (Machine = 645 -> 1, 2)      //  Skip GETLP code.
108           Outop (Tsbbp)
109           Param := LabMaxSSP
110           OutData (ArgCount)
111           if ArgLen > MaxArgOffset do MaxArgOffset := ArgLen
112           DisclaimRegister (F)
113           unless Result = 0 do ClaimRegister (Qr, Result)
114           IndicatorsSetBy := 0
115      $)
116 
117 and CreateSystemArglist (Nargs) be
118      $(   ArgCount, ArgLen := Nargs, Nargs * 4 + 2
119           let T = list Nargs lshift 19 | 4, Nargs lshift 19
120           AddLiteral (T, 2, "arglist header", 2)
121           Outop (Ldaq)
122           Address, Tag, Param, Comment := 0, StackRefTag, LabMaxSSP, "arg count"
123           Outop (Staq)
124      $)
125 and StoreSystemArg (i, Arg, Offset, Type, Length, StringSw) be
126      $(   if StringSw & Offset = 0 do Offset := Machine = 645 -> (table CONSTANT_S, 9, 0), (table CONSTANT_S, 18, 0)
127           let Pr = LoadPointer (Arg, AnyPr)
128           if Machine = 6180 & Offset ne 0 do
129                $(   let Xr = LoadIndex (Offset, AnyXr)
130                     Outop3 (Abd, 0, FormTag (Pr) | FormTag (Xr))
131                $)
132           Address, Tag, Param := i * 2 + 2, StackRefTag, LabMaxSSP
133           Outop (FormOpcode (Stpap, Pr))
134           if Machine = 645 & Offset ne 0 do
135                $(   let q = LoadRegister (Offset, AorQr)
136                     Outop3 (FormOpcode (Als, q), 9, 0)
137                     Outop3 (FormOpcode (Ana, q), $8077000, Dl)
138                     Address, Tag, Param := i * 2 + 2, StackRefTag, LabMaxSSP
139                     Address, Tag, Param := i * 2 + 3, StackRefTag, LabMaxSSP
140                     Outop (FormOpcode (Orsa, q))
141                $)
142           let ConstantPart, RegPart, CellOffset = 1 lshift 35, 0, 0
143           test Length = 0
144           then if StringSw do
145                $(   RegPart := GetRegister (AorQr)
146                     Outop3 (FormOpcode (Lda, RegPart), 0, FormTag (Pr))
147                     Outop3 (FormOpcode (Arl, RegPart), (Machine = 645 -> 27, 18), 0)
148                $)
149           or test IsNumber (Length)
150           then ConstantPart := ConstantPart | (EvalNumber (Length!0, Length!1) & $877777777)
151           or   $(   RegPart := LoadRegister (Length, AorQr)
152                     Literal ($877777777, 0)
153                     Outop (FormOpcode (Ana, RegPart))
154                $)
155 
156           test IsNumber (Type)
157           then ConstantPart := ConstantPart | (EvalNumber (Type!0, Type!1) lshift 29)
158           or   $(   if RegPart ne 0 do
159                          $(   CellOffset := ArgLen
160                               ArgLen := ArgLen + 1
161                               Address, Tag, Param := CellOffset, StackRefTag, LabMaxSSP
162                               Outop (FormOpcode (Sta, RegPart))
163                          $)
164                     RegPart := LoadRegister (Type, AorQr)
165                     Outop3 (FormOpcode (Als, RegPart), 29, 0)
166                $)
167           test RegPart = 0
168           then AddLiteral (lv ConstantPart, 1, "descriptor", 0)
169           or   $(   Literal (ConstantPart, 0)
170                     Outop (FormOpcode (Ora, RegPart))
171                     let Op = nil
172                     test CellOffset = 0
173                     then $(   CellOffset := ArgLen
174                               ArgLen := ArgLen + 1
175                               Op := Sta
176                          $)
177                     or Op := Orsa
178                     Address, Tag, Param := CellOffset, StackRefTag, LabMaxSSP
179                     Outop (FormOpcode (Op, RegPart))
180                     Address, Tag, Param := CellOffset, StackRefTag, LabMaxSSP
181                $)
182           Outop (FormOpcode (Eapap, Pr))
183           Address, Tag, Param := i * 2 + ArgCount * 2 + 2, StackRefTag, LabMaxSSP
184           Outop (FormOpcode (Stpap, Pr))
185           DisclaimRegister (Arg)
186           unless Offset = 0 do DisclaimRegister (Offset)
187           DisclaimRegister (Type)
188           unless Length = 0 do DisclaimRegister (Length)
189      $)
190 and CompSystemCall (F) be
191      $(   if ArgLen > MaxArgOffset do MaxArgOffset := ArgLen
192           test Machine = 645
193           then $(   Outop3 (Stb, 0, Sp)
194                     Outop3 (Sreg, 8, Sp)
195                $)
196           or   $(   Outop3 (Sxl1, 8, Sp)                    //  Save stack index in stack frame header.
197                     Outop3 (Stplp, 24, Sp)
198                $)
199           LoadPointer (F, Bpr)
200           Address, Tag, Param := 0, StackRefTag, LabMaxSSP
201           Outop (Eapap)
202           Outop4 (Tsblp, 30, Sb | Star, "Multics call operator")
203           if Machine = 6180 do
204                $(   Outop3 (Lxl1, 8, Sp)
205                     Outop3 (Lprplp, 1, StackRefTag)
206                $)
207           DisclaimRegister (F)
208           IndicatorsSetBy := 0
209      $)
210 
211 and ResultBlockBegin () be
212      $(   let New = Newvec (1)
213           New!0, New!1 := ResultInfo, ResultInfoList
214           ResultInfo, ResultInfoList := 0, New
215      $)
216 and ResultSet (Desc) be
217      $(   ResultInfo := LoadAppropriateRegister (Desc, ResultInfo)
218           DisclaimRegister (Desc)
219      $)
220 and ResultGet (Desc) be
221      $(   ClaimRegister (ResultInfo, Desc)
222           let Old = ResultInfoList
223           ResultInfo, ResultInfoList := Old!0, Old!1
224           Freevec (Old, 1)
225      $)
226 
227 and Compstring (s) be
228      $(   let v = vec Vmax
229           let Len = FormStringconst (s, v)
230           AddLiteral (v, Len + 1, s, 0)
231      $)
232 and Comptable (t) be
233      $(   let v = Newvec (t!0)
234           for i = 0 to t!0 - 1 do v!i := EvalNumber (t!(i * 2 + 1), t!(i * 2 + 2))
235           AddLiteral (v, t!0, "a table", 2)
236           Freevec (v, t!0)
237      $)
238 let Compexternal (s) = valof
239      $(   let p = LinkList
240           until p = 0 do
241                $(   if EqualString (s, p!1) resultis p!2
242                     p := p!0
243                $)
244           let L = Nextparam ()
245           LinkList := List4 (LinkList, s, L, 0)
246           resultis L
247      $)
248 and Compfinish () be
249           Outop4 (Tra, 34, Sb | Star, "Multics return")
250 and Compgoto (p) be
251      $(   SetupAddr (p)
252           Outop (Tra)
253           DisclaimRegister (p)
254      $)