# HG changeset patch # User Mike Pavone # Date 1377669739 25200 # Node ID 49bca64871783813a476388fc1b142e011738237 # Parent 3b13ced3b5627ec7d603e4389acb01ae47e475d3 Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions. diff -r 3b13ced3b562 -r 49bca6487178 modules/il.tp --- a/modules/il.tp Tue Aug 27 22:53:30 2013 -0700 +++ b/modules/il.tp Tue Aug 27 23:02:19 2013 -0700 @@ -57,7 +57,7 @@ _inb recordUsage: tracker at: 0 | address withSize: _size _out recordUsage: tracker at: 1 | address withSize: _size } - assignRegs:withSource <- :assignments :regSrc { + assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { newa <- if: (not: (_ina isInteger?)) { _ina assign: assignments withSource: regSrc } else: { _ina } @@ -82,7 +82,7 @@ } _out recordUsage: tracker at: 1 | address withSize: _size } - assignRegs:withSource <- :assignments :regSrc { + assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { newin <- if: (not: (_in isInteger?)) { _in assign: assignments withSource: regSrc } else: { _in } @@ -104,7 +104,7 @@ _arg recordUsage: tracker at: address withSize: _size } } - assignRegs:withSource <- :assignments :regSrc { + assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { newarg <- if: (not: (_arg isInteger?)) { _arg assign: assignments withSource: regSrc } else: { _arg } @@ -350,7 +350,7 @@ arg recordUsage: tracker at: address withSize: q } } - assignRegs:withSource <- :assignments :regSrc { + assignRegs:at:withSource:andUsage <- :assignments :address :regSrc :usage { newtarget <- if: (_target isString?) { _target } else: { _target assign: assignments withSource: regSrc } @@ -359,9 +359,21 @@ arg assign: assignments withSource: regSrc } } - //TODO: Save caller-save regs if necessary - //TODO: Add instructions for moving arguments to proper regs/stack locations - call: newtarget withArgs: newargs + newcall <- call: newtarget withArgs: newargs + regSrc returnAll + raddress <- address reverse + foreach: (usage liveArgsAt: raddress) :_ arg { + regSrc allocArg: (arg num) + } + foreach: (usage liveRegsAt: raddress) :_ reg { + regSrc allocSpecific: (assignments get: reg) + } + tosave <- regSrc needSaveForCall + if: (tosave length) > 0 { + save: tosave #[newcall] + } else: { + newcall + } } } } @@ -388,12 +400,16 @@ inst recordUsage: tracker at: idx | address } } - assignRegs:withSource <- :assignments :regSrc { - newskip <- _toskip map: :inst { - inst assignRegs: assignments withSource: regSrc + assignRegs:at:withSource:andUsage <- :assignments :address :regSrc :usage { + newskip <- #[] + foreach: _toskip :idx inst { + newskip append: (inst assignRegs: assignments at: idx | address withSource: regSrc andUsage: usage) } skipIf: _cond newskip } + to2OpInst <- { + skipIf: _cond (to2Op: _toskip) + } } } save <- :regs :scope{ @@ -408,6 +424,9 @@ } name . " " . (regs join: " ") . " {" . block . "}" } + to2OpInst <- { + save: regs (to2Op: scope) + } } } @@ -435,6 +454,15 @@ } _maxUses <- 0 + liveFrom:to <- :regs :from :to { + live <- #[] + foreach: regs :reg usage { + if: ((usage lastUsage) addrGreatEq: from) && ((usage firstUsage) addrLessEq: to) { + live append: reg + } + } + live + } regUsage <- #{ reg:usedAt:withSize <- :reg :address :size { raddress <- address reverse @@ -453,6 +481,14 @@ } usage usedAt: raddress withSize: size } + + liveRegsAt <- :address { + _regMap liveFrom: address to: address + } + liveArgsAt <- :address { + _argMap liveFrom: address to: address + } + print <- { foreach: _regMap :reg usage { print: (string: reg) . " | " . (string: usage) . "\n" @@ -501,16 +537,6 @@ greateq } - liveFrom:to <- :regs :from :to { - live <- #[] - foreach: regs :reg usage { - if: ((usage lastUsage) addrGreatEq: from) && ((usage firstUsage) addrLessEq: to) { - live append: reg - } - } - live - } - _assignments <- dict linear curuses <- _maxUses while: { curuses > 0 && (_assignments length) < (_regMap length) } do: { @@ -540,11 +566,11 @@ print: (string: reg) . " = " . assign . "\n" } - withassign <- map: instarr :inst { - inst assignRegs: _assignments withSource: regSrc + withassign <- #[] + foreach: instarr :idx inst { + withassign append: (inst assignRegs: _assignments at: [idx] withSource: regSrc andUsage: regUsage) } psave <- regSrc needSaveProlog - print: "Regs that need saving in prolog: " . (psave join: ",") . "\n" if: (psave length) > 0 { withassign <- #[save: psave withassign] } @@ -573,7 +599,11 @@ } newarr append: (op1: (inst opcode) val: (inst out) size: (inst size)) } else: { - newarr append: inst + if: (inst opcode) = _skipif || (inst opcode) = _save { + newarr append: (inst to2OpInst) + } else: { + newarr append: inst + } } } } @@ -598,7 +628,7 @@ } print: "\n\nUsage:\n\n" fiba <- allocRegs: fib withSource: (x86 regSource) - print: "\n\nAFter Assignment:\n\n" + print: "\n\nAfter Assignment:\n\n" foreach: fiba :idx inst { print: (string: inst) . "\n" }