Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /MLRISC/trunk/c-call/test/c-sparc-test.sml
ViewVC logotype

Diff of /MLRISC/trunk/c-call/test/c-sparc-test.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3173, Thu Jul 31 01:11:27 2008 UTC revision 3177, Fri Aug 1 22:53:25 2008 UTC
# Line 83  Line 83 
83      structure Region    = UserRegion      structure Region    = UserRegion
84      structure Extension = UserExtension)      structure Extension = UserExtension)
85    
 (*  
  * This module controls how we handle user extensions.  Since we don't  
  * have any yet.  This is just a bunch of dummy routines.  
  *)  
 functor SparcMLTreeExtComp  
    (structure T : MLTREE  
                 where Extension = UserExtension  
     structure I : SPARCINSTR  
                 where T = T  
     structure Stream : MLTREE_STREAM  
                 where T = I.T  
     structure CFG : CONTROL_FLOW_GRAPH  
                 where I = I  
                   and P = Stream.S.P  
    ) : MLTREE_EXTENSION_COMP =  
 struct  
    structure TS = Stream  
    structure I = I  
    structure T = I.T  
    structure C = I.C  
    structure Ext = UserExtension  
    structure CFG = CFG  
    structure SparcCompInstrExt =  
      SparcCompInstrExt(structure I = I structure CFG = CFG structure TS=Stream)  
   
    type reducer =  
      (I.instruction,C.cellset,I.operand,I.addressing_mode, CFG.cfg) TS.reducer  
   
    fun unimplemented _ = MLRiscErrorMsg.impossible "SparcMLTreeExtComp"  
   
    val compileSext  = SparcCompInstrExt.compileSext  
    val compileRext  = unimplemented  
    val compileCCext = unimplemented  
    val compileFext  = unimplemented  
 end  
86    
87  (*---------------------------------------------------------------------------  (*---------------------------------------------------------------------------
88   * Backend specific stuff.  You'll need one instance of these things   * Backend specific stuff.  You'll need one instance of these things
# Line 172  Line 137 
137      structure PseudoOps = PseudoOps (structure Client = Client)      structure PseudoOps = PseudoOps (structure Client = Client)
138    end    end
139    
140  structure Stream = InstructionStream(PseudoOps.PseudoOps)  structure SparcStream = InstructionStream(PseudoOps.PseudoOps)
141    structure SparcMLTreeStream =
142        MLTreeStream
143          (structure T = SparcMLTree
144           structure S = SparcStream)
145    
146  (*  (*
147   * The assembler   * The assembler
148   *)   *)
149  structure SparcAsm = SparcAsmEmitter  structure SparcAsm = SparcAsmEmitter
150     (structure Instr = SparcInstr     (structure Instr = SparcInstr
151      structure Stream = Stream      structure Stream = SparcStream
152      structure Shuffle = SparcShuffle      structure Shuffle = SparcShuffle
153      structure S = Stream      structure S = SparcStream
154      structure MLTreeEval = SparcMLTreeEval      structure MLTreeEval = SparcMLTreeEval
155      val V9 = false  (* we'll generate V8 instructions for now *)      val V9 = false  (* we'll generate V8 instructions for now *)
156     )     )
157    
158  (*  structure SparcPseudoInstrs : SPARC_PSEUDO_INSTR =
  * Because of various Sparc related ugliness.  Pseudo instructions  
  * related to integer multiplication/division are handled via callbacks.  
  * Here we can decide what actual code to generate.  Here we only  
  * handle a subset of of the pseudo instructions.  
  *)  
 structure SparcPseudoInstrs =  
159  struct  struct
160    structure I = SparcInstr    structure I = SparcInstr
161    structure C = SparcInstr.C    structure C = I.C
162    
163    type format1 =    type format1 =
164         {r:CellsBasis.cell, i:I.operand, d:CellsBasis.cell} *         {r:CellsBasis.cell, i:I.operand, d:CellsBasis.cell} *
# Line 207  Line 170 
170    
171    fun error msg = MLRiscErrorMsg.impossible ("SparcPseudoInstrs."^msg)    fun error msg = MLRiscErrorMsg.impossible ("SparcPseudoInstrs."^msg)
172    
173    fun umul32({r, i, d}, reduceOpnd) = [I.ARITH{a=I.UMUL,r=r,i=i,d=d}]    val delta = 0 (*SparcSpec.framesize*) (* initial value of %fp - %sp *)
174    fun smul32({r, i, d}, reduceOpnd) = [I.ARITH{a=I.SMUL,r=r,i=i,d=d}]  
175    fun udiv32({r,i,d},reduceOpnd) =    (* runtime system dependent; the numbers are relative to %sp but
176        [I.WRY{r=C.r0,i=I.REG(C.r0)},I.ARITH{a=I.UDIV,r=r,i=i,d=d}]     * we need offsets relative to %fp, hence the adjustment by delta *)
177      val floatTmpOffset = I.IMMED (88 - delta)
178      val umulOffset = I.IMMED (80 - delta)
179      val smulOffset = I.IMMED (72 - delta)
180      val udivOffset = I.IMMED (84 - delta)
181      val sdivOffset = I.IMMED (76 - delta)
182    
183      val stack = () (*CPSRegions.stack*)
184    
185      val native = true  (* use native versions of the instructions? *)
186    
187    fun sdiv32({r,i,d},reduceOpnd) =    fun umul_native({r, i, d}, reduceOpnd) =
188          [I.arith{a=I.UMUL,r=r,i=i,d=d}]
189    
190      val TNE = I.ticc{t=I.BNE,cc=I.ICC,r=C.r0,i=I.IMMED 7}
191      val TVS = I.ticc{t=I.BVS,cc=I.ICC,r=C.r0,i=I.IMMED 7}
192    
193          (* overflows iff Y != (d ~>> 31) *)
194      fun smult_native({r, i, d}, reduceOpnd) =
195    let val t1 = C.newReg()    let val t1 = C.newReg()
196    in  [I.SHIFT{s=I.SRA,r=r,i=I.IMMED 31,d=t1},            val t2 = C.newReg()
197         I.WRY{r=t1,i=I.REG(C.r0)},        in  [I.arith{a=I.SMUL,r=r,i=i,d=d},
198         I.ARITH{a=I.SDIV,r=r,i=i,d=d}             I.shift{s=I.SRA,r=d,i=I.IMMED 31,d=t1},
199               I.rdy{d=t2},
200               I.arith{a=I.SUBCC,r=t1,i=I.REG t2,d=C.r0},
201               TNE
202        ]        ]
203    end    end
204    
205    fun cvti2d({i,d},reduceOpnd) = error "cvti2d"    fun smul_native({r, i, d}, reduceOpnd) =
206      (* There is no data path between integer and floating point registers.        [I.arith{a=I.SMUL,r=r,i=i,d=d}]
207         So we actually have to use some memory location for temporary  
208         This is commented out for now.    fun udiv_native({r,i,d},reduceOpnd) =
209       *)        [I.wry{r=C.r0,i=I.REG C.r0},
210      (*         I.arith{a=I.UDIV,r=r,i=i,d=d}]
211        [I.STORE{s=I.ST,r=C.stackptrR,i=floatTmpOffset,d=reduceOpnd i,mem=stack},  
212         I.FLOAD{l=I.LDF,r=C.stackptrR,i=floatTmpOffset,d=d,mem=stack},     (* May overflow if MININT div -1 *)
213         I.FPop1{a=I.FiTOd,r=d,d=d}    fun sdivt_native({r,i,d},reduceOpnd) =
214          let val t1 = C.newReg()
215          in  [I.shift{s=I.SRA,r=r,i=I.IMMED 31,d=t1},
216               I.wry{r=t1,i=I.REG C.r0},
217               I.arith{a=I.SDIVCC,r=r,i=i,d=d},
218               TVS
219              ]
220          end
221    
222      fun sdiv_native({r,i,d},reduceOpnd) =
223          let val t1 = C.newReg()
224          in  [I.shift{s=I.SRA,r=r,i=I.IMMED 31,d=t1},
225               I.wry{r=t1,i=I.REG C.r0},
226               I.arith{a=I.SDIV,r=r,i=i,d=d}
227        ]        ]
228          end
229    
230      (*
231       * Registers %o2, %o3 are used to pass arguments to ml_mul and ml_div
232       * Result is returned in %o2.
233      *)      *)
234      val r10 = C.GPReg 10
235      val r11 = C.GPReg 11
236    
237      fun callRoutine(offset,reduceOpnd,r,i,d) =
238      let val addr = C.newReg()
239          val defs = C.addReg(r10,C.empty)
240          val uses = C.addReg(r10,C.addReg(r11,C.empty))
241          fun copy{dst, src, tmp} =
242              I.COPY{k=CellsBasis.GP, sz=32, dst=dst, src=src, tmp=tmp}
243      in
244          [copy{src=[r,reduceOpnd i],dst=[r10,r11],tmp=SOME(I.Direct(C.newReg()))},
245           I.load{l=I.LD,r=C.frameptrR,i=offset,d=addr,mem=stack},
246           I.jmpl{r=addr,i=I.IMMED 0,d=C.linkReg,defs=defs,uses=uses,
247                  cutsTo=[],nop=true,mem=stack},
248           copy{src=[r10],dst=[d],tmp=NONE}
249          ]
250      end
251    
252      fun umul({r, i, d}, reduceOpnd) = callRoutine(umulOffset,reduceOpnd,r,i,d)
253      fun smultrap({r, i, d}, reduceOpnd) = callRoutine(smulOffset,reduceOpnd,r,i,d)
254      fun udiv({r, i, d}, reduceOpnd) = callRoutine(udivOffset,reduceOpnd,r,i,d)
255      fun sdivtrap({r, i, d}, reduceOpnd) = callRoutine(sdivOffset,reduceOpnd,r,i,d)
256    
257      fun cvti2d({i, d}, reduceOpnd) =
258          [I.store{s=I.ST,r=C.frameptrR,i=floatTmpOffset,d=reduceOpnd i,mem=stack},
259           I.fload{l=I.LDF,r=C.frameptrR,i=floatTmpOffset,d=d,mem=stack},
260           I.fpop1{a=I.FiTOd,r=d,d=d}
261          ]
262    fun cvti2s _ = error "cvti2s"    fun cvti2s _ = error "cvti2s"
263    fun cvti2q _ = error "cvti2q"    fun cvti2q _ = error "cvti2q"
264    
265    fun smul32trap _ = error "smul32trap"       (* Generate native versions of the instructions *)
266    fun sdiv32trap _ = error "sdiv32trap"    val umul32 = if native then umul_native else umul
267      val smul32 : format1 =
268          if native then smul_native else (fn _ => error "smul32")
269      val smul32trap = if native then smult_native else smultrap
270      val udiv32 = if native then udiv_native else udiv
271      val sdiv32 : format1 =
272          if native then sdiv_native else (fn _ => error "sdiv32")
273      val sdiv32trap = if native then sdivt_native else sdivtrap
274    
275    val overflowtrap32 = [] (* not needed *)    val overflowtrap32 = (* tvs 0x7 *)
276                           [I.ticc{t=I.BVS,cc=I.ICC,r=C.r0,i=I.IMMED 7}]
277    val overflowtrap64 = [] (* not needed *)    val overflowtrap64 = [] (* not needed *)
278    
279    
280  end  end
281    
282  structure SparcMLTreeHash =  structure SparcMLTreeHash =
# Line 257  Line 295 
295  structure SparcAsmEmitter =  structure SparcAsmEmitter =
296    SparcAsmEmitter(structure Instr=SparcInstr    SparcAsmEmitter(structure Instr=SparcInstr
297                    structure Shuffle=SparcShuffle                    structure Shuffle=SparcShuffle
298                    structure S = Stream                    structure S = SparcStream
299                    structure MLTreeEval=SparcMLTreeEval                    structure MLTreeEval=SparcMLTreeEval
300                    val V9 = false)                    val V9 = false)
301    
# Line 270  Line 308 
308        structure InsnProps = SparcProps        structure InsnProps = SparcProps
309        structure Asm = SparcAsmEmitter)        structure Asm = SparcAsmEmitter)
310    
311    structure SparcFlowGraph = BuildFlowgraph
312                (structure Props = SparcProps
313                 structure Stream = SparcStream
314                 structure CFG = SparcCFG)
315    
316    structure SparcExpand = CFGExpandCopies (structure CFG=SparcCFG
317                                             structure Shuffle = SparcShuffle)
318    structure SparcBlockPlacement = DefaultBlockPlacement(SparcCFG)
319    
320    structure SparcEmit = CFGEmit (
321                 structure CFG = SparcCFG
322                 structure E = SparcAsmEmitter)
323    
324    structure SparcCCall = SparcCCallFn (
325                             structure T = SparcMLTree
326                             fun ix x = raise Fail "")
327    
328  (*  (*
329     * This module controls how we handle user extensions.  Since we don't
330     * have any yet.  This is just a bunch of dummy routines.
331     *)
332    structure SparcMLTreeExtComp : MLTREE_EXTENSION_COMP =
333    struct
334       structure TS = SparcMLTreeStream
335       structure I = SparcInstr
336       structure T = SparcMLTree
337       structure C = I.C
338       structure Ext = UserExtension
339       structure CFG = SparcCFG
340       structure SparcCompInstrExt =
341         SparcCompInstrExt(structure I = I structure CFG = CFG structure TS=SparcMLTreeStream)
342    
343       type reducer =
344         (I.instruction,C.cellset,I.operand,I.addressing_mode, CFG.cfg) TS.reducer
345       fun unimplemented _ = MLRiscErrorMsg.impossible "SparcMLTreeExtComp"
346    
347       val compileSext  = SparcCompInstrExt.compileSext
348       val compileRext  = unimplemented
349       val compileCCext = unimplemented
350       val compileFext  = unimplemented
351    end
352    
353      structure MLTreeComp=      structure MLTreeComp=
354         Sparc(structure SparcInstr = SparcInstr         Sparc(structure SparcInstr = SparcInstr
355               structure SparcMLTree = SparcMLTree               structure SparcMLTree = SparcMLTree
356               structure PseudoInstrs = SparcPseudoInstrs               structure PseudoInstrs = SparcPseudoInstrs
357               structure ExtensionComp = SparcMLTreeExtComp               structure ExtensionComp = SparcMLTreeExtComp
                (structure I = SparcInstr  
                 structure T = SparcMLTree  
                 structure Stream = Stream  
                 structure CFG = SparcCFG  
                )  
358               val V9 = false               val V9 = false
359               val muluCost = ref 5               val muluCost = ref 5
360               val multCost = ref 3               val multCost = ref 3
# Line 289  Line 363 
363               val registerwindow = ref false               val registerwindow = ref false
364               val useBR = ref false               val useBR = ref false
365              )              )
366  *)  
367  (*  
368  (*---------------------------------------------------------------------------      structure InsnProps = SparcProps
  * Okay.  Finally, we can tie the front-end and back-end together.  
  *---------------------------------------------------------------------------*)  
 structure SparcBackEnd =  
    BackEnd  
    (structure Flowgraph  = SparcFlowGraph  
     structure MLTreeComp = SparcMLTreeComp  
     structure Asm        = SparcAsm  
369    
370      structure RA =      structure RA =
371        RISC_RA        RISC_RA
372        (structure I         = SparcInstr        (structure I         = SparcInstr
373         structure Flowgraph = Flowgraph         structure C         = CellsBasis
374         structure Asm       = Asm         structure T = SparcMLTree
375              structure CFG       = SparcCFG
376         structure InsnProps = InsnProps         structure InsnProps = InsnProps
        structure Spill     = RASpill(structure Asm = Asm  
                                      structure InsnProps = InsnProps)  
377         structure Rewrite   = SparcRewrite(SparcInstr)         structure Rewrite   = SparcRewrite(SparcInstr)
378              structure SpillInstr= SparcSpillInstr(SparcInstr)
379              structure Asm       = SparcAsmEmitter
380         structure SpillHeur = ChaitinSpillHeur         structure SpillHeur = ChaitinSpillHeur
381         structure C         = I.C            structure Spill     = RASpill(structure InsnProps = InsnProps
382                                            structure Asm = SparcAsmEmitter)
383    
384         val sp = C.stackptrR            structure SpillTable = SpillTable(val initialSpillOffset = 0 (* This is probably wrong!!!!! *)
385                val spillAreaSz = 4000
386                val architecture = "Sparc" )
387              val fp = I.C.frameptrR
388         val spill = UserRegion.spill         val spill = UserRegion.spill
389              datatype spillOperandKind = SPILL_LOC | CONST_VAL
390              type spill_info = unit
391              fun beforeRA _ = SpillTable.beginRA()
392    
        structure SpillTable = SpillTable  
            (val initialSpillOffset = 0 (* This is probably wrong!!!!! *)  
             val spillAreaSz = 4000  
393              val architecture = "Sparc"              val architecture = "Sparc"
            )  
        open SpillTable  
394    
395         fun pure(I.ANNOTATION{i,...}) = pure i         fun pure(I.ANNOTATION{i,...}) = pure i
396           | pure(I.LOAD _) = true              | pure(I.INSTR(I.LOAD _)) = true
397           | pure(I.FLOAD _) = true              | pure(I.INSTR(I.FLOAD _)) = true
398           | pure(I.SETHI _) = true              | pure(I.INSTR(I.SETHI _)) = true
399           | pure(I.SHIFT _) = true              | pure(I.INSTR(I.SHIFT _)) = true
400           | pure(I.FPop1 _) = true              | pure(I.INSTR(I.FPop1 _)) = true
401           | pure(I.FPop2 _) = true              | pure(I.INSTR(I.FPop2 _)) = true
402           | pure _ = false           | pure _ = false
403    
404         (* I'm assuming only r0 and the stack pointer is dedicated *)            (* make copy *)
405         structure Int =         structure Int =
406         struct         struct
407             val dedicated  = [I.C.stackptrR, I.C.GPReg 0]             val dedicated  = [I.C.stackptrR, I.C.GPReg 0]
# Line 339  Line 409 
409               C.SortedCells.return               C.SortedCells.return
410                (C.SortedCells.difference(                (C.SortedCells.difference(
411                  C.SortedCells.uniq(                  C.SortedCells.uniq(
412                    C.Regs C.GP {from=0, to=31, step=1}),                     SparcCells.Regs C.GP {from=0, to=31, step=1}),
413                  C.SortedCells.uniq dedicated)                  C.SortedCells.uniq dedicated)
414                )                )
415    
416            fun copy((rds as [_], rss as [_]), _) =               fun mkDisp loc = T.LI(T.I.fromInt(32, SpillTable.get loc))
417                I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=NONE}               fun spillLoc{info, an, cell, id} =
418              | copy((rds, rss), I.COPY{tmp, ...}) =                    {opnd=I.Displace{base=fp, disp=mkDisp(RAGraph.FRAME id), mem=spill},
419                I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=tmp}                     kind=SPILL_LOC}
420    
421            (* spill copy temp *)               val mode = RACore.NO_OPTIMIZATION
           fun spillCopyTmp(_,I.COPY{dst,src,tmp,impl},loc) =  
               I.COPY{dst=dst, src=src, impl=impl,  
                      tmp=SOME(I.Displace{base=sp, disp=get loc})}  
   
           (* spill register *)  
            fun spillInstr{an,src,spilledCell,spillLoc} =  
                [I.STORE{s=I.ST, r=sp, i=I.IMMED(get spillLoc), d=src,  
                       mem=spill}]  
   
           (* reload register *)  
            fun reloadInstr{an,dst,spilledCell,spillLoc} =  
                 [I.LOAD{l=I.LD, r=sp, i=I.IMMED(get spillLoc), d=dst,  
                       mem=spill}]  
422         end         end
423    
424         structure Float =         structure Float =
425         struct         struct
426          fun fromto(n, m, inc) = if n>m then [] else n :: fromto(n+inc, m, inc)
427              val avail =  SparcCells.Regs C.FP {from=0, to=30, step=2}
428            val dedicated = []            val dedicated = []
           val avail     = C.Regs C.FP {from=0, to=31, step=2}  
429    
430            fun copy((fds as [_], fss as [_]), _) =                fun mkDisp loc = T.LI(T.I.fromInt(32, SpillTable.getF loc))
               I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=NONE}  
             | copy((fds, fss), I.FCOPY{tmp, ...}) =  
               I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=tmp}  
   
           fun spillCopyTmp(_,I.FCOPY{dst,src,tmp,impl},loc) =  
               I.FCOPY{dst=dst, src=src, impl=impl,  
                       tmp=SOME(I.Displace{base=sp, disp=getF loc})}  
431    
432            fun spillInstr(_, d,loc) =               fun spillLoc(S, an, loc) =
433                [I.FSTORE{s=I.STDF, r=sp, i=I.IMMED(getF loc), d=d, mem=spill}]                  I.Displace{base=fp, disp=mkDisp(RAGraph.FRAME loc), mem=spill}
434    
435            fun reloadInstr(_,d,loc) =               val mode = RACore.NO_OPTIMIZATION
               [I.FLOAD{l=I.LDDF, r=sp, i=I.IMMED(getF loc), d=d, mem=spill}]  
436         end         end
437        )        )
438     )  
439    structure Cells = SparcInstr.C
440    structure T = SparcMLTree
441    structure CFG = SparcCFG
442    structure FlowGraph = SparcFlowGraph
443        val wordTy = 32
444    
445        fun gen (functionName, stms, result) = let
446               val insnStrm = FlowGraph.build()
447               val stream as SparcStream.STREAM
448               { beginCluster,  (* start a cluster *)
449                 endCluster,    (* end a cluster *)
450                 emit,          (* emit MLTREE stm *)
451                 defineLabel,   (* define a local label *)
452                 entryLabel,    (* define an external entry *)
453                 exitBlock,     (* mark the end of a procedure *)
454                 pseudoOp,      (* emit a pseudo op *)
455                 annotation,    (* add an annotation *)
456                 ... } =
457                 MLTreeComp.selectInstructions insnStrm
458            fun doit () = (
459                beginCluster 0;      (* start a new cluster *)
460                pseudoOp PseudoOpsBasisTyp.TEXT;
461                pseudoOp (PseudoOpsBasisTyp.EXPORT [functionName]);
462                entryLabel functionName; (* define the entry label *)
463                List.app emit stms; (* emit all the statements *)
464                exitBlock result;
465                endCluster [])
466            val cfg = doit ()
467            val cfg = RA.run cfg
468            val cfg = SparcExpand.run cfg
469            in
470             (cfg, stream)        (* end the cluster *)
471           end
472    
473        fun dumpOutput (cfg, stream) = let
474            val (cfg as Graph.GRAPH graph, blocks) =
475                    SparcBlockPlacement.blockPlacement cfg
476            val CFG.INFO{annotations=an, data, decls, ...} = #graph_info graph
477            in
478              SparcEmit.asmEmit (cfg, blocks)
479            end (* dumpOutput *)
480    
481    
482        fun codegen (functionName, target, proto, initStms, args) = let
483            val _ = Label.reset()
484    
485            val [functionName, target] = List.map Label.global [functionName, target]
486    
487            (* construct the C call *)
488            val {result, callseq} = SparcCCall.genCall {
489                       name=T.LABEL target,
490                       paramAlloc=fn _ => false,
491    (* FIXME *)
492                       structRet=fn _ => T.REG(32, SparcCells.GPReg 0),
493                       saveRestoreDedicated=fn _ => {save=[], restore=[]},
494                       callComment=NONE,
495                       proto=proto,
496                       args=args}
497    
498            fun wordLit i = T.LI (T.I.fromInt (wordTy, i))
499    
500            val stms = List.concat [
501                       initStms,
502                       callseq,
503                       [T.RET []]]
504    
505    (*      val _ = List.all (fn stm => ChkTy.check stm
506                                        orelse raise Fail ("typechecking error: "^SparcMTC.SparcMLTreeUtils.stmToString stm))
507                    stms
508  *)  *)
509    
510  in  in
511  structure SparcTest = struct end             dumpOutput(gen (functionName, stms, result))
512            end
513    
514        val GP = SparcCells.GPReg
515        val FP = SparcCells.FPReg
516    
517        fun greg r = GP r
518        fun oreg r = GP (r + 8)
519        fun ireg r = GP (r + 24)
520        fun freg r = FP r
521        fun reg32 r = T.REG (32, r)
522        fun freg64 r = T.FREG (64, r)
523        fun LI i = T.LI (T.I.fromInt (32, i))
524    
525    
526    in
527    structure SparcTest = GenTestFn (
528                      structure T = SparcMLTree
529                      structure CCall = SparcCCall
530                      structure Cells = SparcCells
531                      val codegen = codegen
532                      val param0 = reg32(oreg 0)
533                      val wordTy = 32)
534  end  end

Legend:
Removed from v.3173  
changed lines
  Added in v.3177

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0