# HG changeset patch # User Michael Pavone # Date 1406524561 25200 # Node ID 2a5d7308e1df9f17c53c9d42f06780a87e3f6030 # Parent d35601d47db17e83436f6498853539b12659a3d5 Cleanup handling of temporaries in gqc diff -r d35601d47db1 -r 2a5d7308e1df code/gqc.tp --- a/code/gqc.tp Sun Jul 27 20:03:34 2014 -0700 +++ b/code/gqc.tp Sun Jul 27 22:16:01 2014 -0700 @@ -1,14 +1,20 @@ { + reg? <- :val { + (object does: val understand?: "isReg?") && (val isReg?) + } + mem? <- :val { + (object does: val understand?: "isMem?") && (val isMem?) + } + mem <- :_addr { #{ addr <- { _addr } string <- { "[" . _addr . "]" } isReg? <- { false } + != <- :other { (not: (mem?: other)) || _addr != (other addr) } + = <- :other { (mem?: other) && _addr = (other addr) } } } - reg? <- :val { - (object does: val understand?: "isReg?") && (val isReg?) - } reg <- :_num { #{ num <- { _num } @@ -94,6 +100,26 @@ ] _tempRegs <- _allTemp + getTemp <- { + if: (_tempRegs empty?) { + //out of regs, use memory + loc <- _nextVar + _nextVar <- _nextVar + 1 + mem: loc + } else: { + r <- _tempRegs value + _tempRegs <- _tempRegs tail + r + } + } + + preserveTemps <- :fun { + saveTempRegs <- _tempRegs + res <- fun: + _tempRegs <- saveTempRegs + res + } + _exprHandlers <- dict hash compileExpr:syms <- :expr :syms { @@ -118,19 +144,22 @@ _opNames set: "xor" "XOR" _exprHandlers set: (ast binary) :expr syms { - startTempRegs <- _tempRegs - l <- compileExpr: (expr left) syms: syms - r <- compileExpr: (expr right) syms: syms + l <- 0 + r <- preserveTemps: { + l <- compileExpr: (expr left) syms: syms + compileExpr: (expr right) syms: syms + } dest <- l if: (reg?: l) { - _tempRegs <- startTempRegs filter: :r { r != l } + //reallocate temp register used by l + //not always safe, needs work + _tempRegs <- _tempRegs filter: :r { r != l } } else: { - dest <- startTempRegs value + dest <- getTemp: prog add: (inst: "MOV" #[ dest l ]) - _tempRegs <- startTempRegs tail } _opNames ifget: (expr op) :i { prog add: (inst: i #[ @@ -161,9 +190,9 @@ info <- syms find: (sym name) else: { error: "this should never happen!" } - startTempRegs <- _tempRegs - v <- compileExpr: (expr assign) syms: syms - _tempRegs <- startTempRegs + v <- preserveTemps: { + compileExpr: (expr assign) syms: syms + } dest <- info def prog add: (inst: "MOV" #[ dest @@ -180,9 +209,9 @@ } _funHandlers set: "direction!" :args syms { dir <- args value - startTempRegs <- _tempRegs - v <- compileExpr: dir syms: syms - _tempRegs <- startTempRegs + v <- preserveTemps: { + compileExpr: dir syms: syms + } if: (reg: 0) != v { prog add: (inst: "MOV" #[ reg: 0 @@ -208,9 +237,9 @@ intNum <- idx + 4 _funHandlers set: name :args syms { ghostIdx <- args value - startTempRegs <- _tempRegs - v <- compileExpr: ghostIdx syms: syms - _tempRegs <- startTempRegs + v <- preserveTemps: { + compileExpr: ghostIdx syms: syms + } if: (reg: 0) != v { prog add: (inst: "MOV" #[ reg: 0 @@ -224,10 +253,10 @@ _funHandlers set: "mapContentsAt" :args syms { x <- args value y <- (args tail) value - startTempRegs <- _tempRegs - x <- compileExpr: x syms: syms - y <- compileExpr: y syms: syms - _tempRegs <- startTempRegs + preserveTemps: { + x <- compileExpr: x syms: syms + y <- compileExpr: y syms: syms + } if: (reg: 0) != x { prog add: (inst: "MOV" #[ reg: 0 @@ -247,8 +276,9 @@ //allow access to raw instructions foreach: #["MOV" "INC" "DEC" "ADD" "SUB" "MUL" "DIV" "AND" "OR" "XOR" "JLT" "JEQ" "JGT" "HLT"] :idx instName { _funHandlers set: instName :args syms { - saveTempRegs <- _tempRegs - args <- args map: :arg { compileExpr: arg syms: syms } + preserveTemps: { + args <- args map: :arg { compileExpr: arg syms: syms } + } prog add: (inst: instName args) } } @@ -262,10 +292,11 @@ end <- prog makeLabel: "loop_end" prog setLabel: top - saveTempRegs <- _tempRegs - l <- compileExpr: (cond left) syms: syms - r <- compileExpr: (cond right) syms: syms - _tempRegs <- saveTempRegs + l <- 0 + r <- preserveTemps: { + l <- compileExpr: (cond left) syms: syms + compileExpr: (cond right) syms: syms + } ok <- true //we need the inverse check in the instruction since a true condition @@ -347,9 +378,9 @@ prog setLabel: lbl syms define: (expr name) lbl } else: { - saveTempRegsExpr <- _tempRegs - v <- compileExpr: expr syms: syms - _tempRegs <- saveTempRegsExpr + v <- preserveTemps: { + compileExpr: expr syms: syms + } } } prog add: (inst: "MOV" #[ @@ -375,10 +406,11 @@ falseLbl <- prog makeLabel: "false" endLbl <- prog makeLabel: "end" - saveTempRegs <- _tempRegs - l <- compileExpr: (cond left) syms: syms - r <- compileExpr: (cond right) syms: syms - _tempRegs <- saveTempRegs + l <- 0 + r <- preserveTemps: { + l <- compileExpr: (cond left) syms: syms + compileExpr: (cond right) syms: syms + } ok <- true @@ -454,9 +486,9 @@ prog setLabel: lbl syms define: (expr name) lbl } else: { - saveTempRegsExpr <- _tempRegs - v <- compileExpr: expr syms: syms - _tempRegs <- saveTempRegsExpr + v <- preserveTemps: { + compileExpr: expr syms: syms + } } } prog add: (inst: "MOV" #[ @@ -472,9 +504,9 @@ prog setLabel: lbl syms define: (expr name) lbl } else: { - saveTempRegsExpr <- _tempRegs - v <- compileExpr: expr syms: syms - _tempRegs <- saveTempRegsExpr + v <- preserveTemps: { + compileExpr: expr syms: syms + } } } prog setLabel: endLbl @@ -493,9 +525,9 @@ handler: (expr args) syms } else: { syms ifDefined: (tc name) :info { - saveTempRegs <- _tempRegs - funArgs <- (expr args) map: :arg { compileExpr: arg syms: syms} - _tempRegs <- saveTempRegs + funArgs <- preserveTemps: { + (expr args) map: :arg { compileExpr: arg syms: syms} + } //save registers that need it needSave <- _allTemp filter: :r { @@ -562,41 +594,40 @@ _compileFun <- :fName fun globsyms { syms <- symbols tableWithParent: globsyms - saveTempRegs <- _tempRegs - foreach: (fun args) :idx arg { - argname <- (if: (arg startsWith?: ":") { arg from: 1 } else: { arg }) - r <- _tempRegs value - _tempRegs <- _tempRegs tail - syms define: argname r - } - - lastexpr <- ((fun expressions) length) - 1 - - //TODO: do 2 passes for labels to allow forward references - foreach: (fun expressions) :idx expr { - if: idx != lastexpr && (expr nodeType) = (ast sym) { - //allow using bare symbols to define labels - prog setLabel: (expr name) - syms define: (expr name) (expr name) - } else: { - saveTempRegsExpr <- _tempRegs - v <- compileExpr: expr syms: syms - _tempRegs <- saveTempRegsExpr - if: idx = lastexpr && (fName != "main") { - //move result to a register - prog add: (inst: "MOV" #[ - reg: 0 - v - ]) - //return instruction - prog add: (inst: "MOV" #[ - reg: 8 - mem: (reg: 7) - ]) + preserveTemps: { + foreach: (fun args) :idx arg { + argname <- (if: (arg startsWith?: ":") { arg from: 1 } else: { arg }) + r <- getTemp: + syms define: argname r + } + + lastexpr <- ((fun expressions) length) - 1 + + //TODO: do 2 passes for labels to allow forward references + foreach: (fun expressions) :idx expr { + if: idx != lastexpr && (expr nodeType) = (ast sym) { + //allow using bare symbols to define labels + prog setLabel: (expr name) + syms define: (expr name) (expr name) + } else: { + v <- preserveTemps: { + compileExpr: expr syms: syms + } + if: idx = lastexpr && (fName != "main") { + //move result to a register + prog add: (inst: "MOV" #[ + reg: 0 + v + ]) + //return instruction + prog add: (inst: "MOV" #[ + reg: 8 + mem: (reg: 7) + ]) + } } } } - saveTempRegs <- _tempRegs } #{