1 //  Initialization and termination code for the code generator phase.
  2 //  Last modified on 06/06/74 at 18:21:14 by R F Mabee.
  3 //  Revisions for 6180 installed in Version 3.4, R F Mabee.
  4 //  First installed as part of bcpl_trans0 with Version 2.7 by R F Mabee.
  5 
  6 //  Copyright (c) 1974 by Massachusetts Institute of Technology and Honeywell Information Systems, Inc.
  7 
  8 //  General permission is granted to copy and use this program, but not to sell it, provided that the above
  9 //  copyright statement is given.  Contact Information Processing Services, MIT, for further information.
 10 //  Please contact R F Mabee at MIT for information on this program and versions for other machines.
 11 
 12 get "bcpl_cg_head"
 13 get "bcpl_metering_head"
 14 
 15 let CgInit () be
 16      $(   NewLiteralsList, OldLiteralsList := 0, 0
 17 
 18           LabTable := Newvec (LabTableSize)
 19           for i = 0 to LabTableSize do LabTable!i := 0
 20 
 21           if Symbols do
 22                $(   SymtabFirst := Newvec (SymtabSize)
 23                     SymtabV, SymtabP := SymtabFirst, 2
 24                $)
 25           if LineMap do
 26                $(   LineMapFirst := Newvec (1)
 27                     LineMapFirst!0 := 1
 28                     LineMapList, LineMapLength := LineMapFirst, 1
 29                $)
 30 
 31           CodeFirst := Newvec (CodeSize)
 32           CodeV, CodeP := CodeFirst, 2
 33           BeginSection (0)
 34 
 35           LinkList, MainEntriesList := 0, 0
 36           CgTempList := 0
 37           LabMaxSSP, MaxSSP := 0, 0
 38           if Crep do
 39                $(   LabMaxSSP := Nextparam ()
 40                     DefineLab (LabMaxSSP, 0)                //  To prevent useless error message.
 41                $)
 42           LabMaxArg, MaxArgOffset := 0, 0
 43           SaveSpaceSize := Machine = 645 -> 4, 2
 44           StackRefTag := Machine = 645 -> Sp | X1, Sb | X1
 45           RegisterTemps, RegisterUsage := Newvec (NumberOfRegisters), Newvec (NumberOfRegisters)
 46           for i = 0 to NumberOfRegisters do RegisterTemps!i, RegisterUsage!i := 0, 0
 47           UsageCounter := 0
 48 
 49           Jumpsw := not Crep
 50           DeferredJumpLabel := 0
 51           EntryLabel, GetLpLabel := 0, 0
 52           Param, Reloc, Comment := 0, 0, 0
 53           IndicatorsSetBy := 0
 54      $)
 55 
 56 and FinishText (StaticList, EntriesList) be
 57      $(   OutLiterals ()
 58           if Crep do Listing := false   //  Avoid lengthy, useless output if in online-debug mode.
 59           if GetLpLabel ne 0 do WriteGetlp ()
 60           if EntryLabel ne 0 do WriteEntry ()
 61           Jumpsw := false
 62           TextLength := LC
 63           if (LC & 1) ne 0 do OutW2 (0, "padding")
 64           TextRelbits := SaveRelbits ()
 65           TotalWords := LC
 66 
 67           BeginSection (0)
 68           WriteDefs (EntriesList)
 69           DefsLength := LC
 70           if (LC & 1) ne 0 do OutW2 (0, "padding")
 71           DefsRelbits := SaveRelbits ()
 72           TotalWords := TotalWords + LC
 73           DefsRelbits := 0              //  Discard, not currently needed for new-format object segment.
 74 
 75           BeginSection (0)
 76           WriteLinkage (StaticList)
 77           LinkageLength := LC
 78           if (LC & 1) ne 0 do OutW2 (0, "padding")
 79           LinkageRelbits := SaveRelbits ()
 80           TotalWords := TotalWords + LC
 81 
 82           BeginSection (0)
 83           WriteSymbol ()                          //  Counts bits in TextRelbits, etc.
 84           SymbolRelbits := SaveRelbits ()
 85           BeginSection (LC)                       //  To Multics this is a part of the symbol section without relbits.
 86           WriteRelBits ()
 87           SymbolLength := LC
 88           SaveRelbits ()                          //  For listing - not part of object segment.
 89           TotalWords := TotalWords + LC
 90 
 91           BeginSection (TotalWords)               //  Use absolute location counter for object map.
 92           WriteObjectMap (TotalWords)
 93           SaveRelbits ()                          //  For listing - not part of object segment.
 94           TotalWords := LC
 95 
 96           if Listing do WriteS (OUTPUT, "*tend*n")
 97           CodeV!0, CodeV!1 := 0, CodeP
 98 
 99 //  Fill in final addresses for all label references in text.
100           let p = CodeFirst
101           until p = 0 do
102                $(   for i = 2 to p!1 - 3 by 3 do switchon p!i & Right into
103                          $(   case CodeSwitch:
104                               case InstructionSwitch:
105                               case DataSwitch:
106                                         let Param = p!i rshift Left
107                                         if Param ne 0 do
108                                              $(   let N = LookupLabel (Param)
109                                                   if N = 0 do CGreport (UndefLab, Param)
110                                                   p!(i + 1) := p!(i + 1) + (N lshift 18)
111                                              $)
112                                         LC := LC + 1
113                                         loop
114 
115                               case LineCountSwitch:
116                                         LineCount := p!(i + 1)
117                                         loop
118 
119                               case LabelSwitch:
120                                         if LC ne p!(i + 2) do CGreport (PhaseError, "FinishText")
121                                         loop
122 
123                               case SectionSwitch:
124                                         LC := p!(i + 1)
125                               default:
126                          $)
127                     p := p!0
128                $)
129      $)
130 and SaveRelbits () = valof
131      $(   if AbsRelBits > 0 do PutAbsBits ()
132           RelbitsList!1 := 0
133           resultis List2 (RelbitsLength * 36 + RelbitsOffset, RelbitsFirst)
134      $)
135 and BeginSection (NewLC) be
136      $(   LC := NewLC
137           RelbitsFirst := Newvec (1)
138           RelbitsFirst!0 := 0
139           RelbitsList := RelbitsFirst
140           RelbitsOffset, RelbitsLength, AbsRelBits := 0, 0, 0
141           PutCode (SectionSwitch, NewLC, RelbitsList)       //  So listing will agree.
142      $)
143 
144 let BuildObject (s) = valof
145      $(   let p, LC = CodeFirst, 0
146           until p = 0 do
147                $(   for i = 2 to p!1 - 3 by 3 do switchon p!i & Right into
148                          $(   case CodeSwitch:
149                               case InstructionSwitch:
150                               case DataSwitch:
151                                         s!LC := p!(i + 1)
152                                         LC := LC + 1
153                               default:
154                          $)
155                     p := p!0
156                $)
157           resultis LC * 36
158      $)
159 
160 and WriteObjectListing () be
161      $(   let p = CodeFirst
162           until p = 0 do
163                $(   for i = 2 to p!1 - 3 by 3 do ListCodeItem (lv p!i)
164                     p := p!0
165                $)
166      $)