def BranchOp(self, i): ops = {il.IFEQ:x.je, il.IFNE:x.jne, il.IFLT:x.jl, il.IFLE:x.jle, il.IFGT:x.jg, il.IFGE:x.jge} code = [ x.movl(x.loc(i.a.type), x.eax), x.cmpl(x.loc(i.b.type), x.eax), ops[i.op](i.result.name) ] #for i in code: #print i return code
def Call(self, i): """Generate code to Call a function""" if isinstance(i.a.type, il.Func): code = [x.call(i.a.type.entry)] else: # Otherwise it is a function pointer. code = [x.call(x.loc(i.a.type, deref=True))] return code
def Iprm(self, i): """Generator code for IPRM : Put an Input Param on the Stack""" if isinstance(i.b.type, il.Func): # this is a function param not a value code = [x.leal(i.b.type.entry, x.eax), x.movl(x.eax, x.mem(x.esp, -(2 + i.a) * 4))] else: code = [x.movl(x.loc(i.b.type), x.eax), x.movl(x.eax, x.mem(x.esp, -(2 + i.a) * 4))] return code
def Rprm(self, i): #print i code = [ x.movl(x.mem(x.esp, -(2+i.a)*4), x.eax), x.movl(x.eax, x.loc(i.result.type)), ] #self.var[i.result] = self.bp_offset #self.bp_offset += 1 return code
def Call(self, i): if isinstance(i.a.type, il.Func): code = [ x.call(i.a.type.entry), ] else: code = [ x.call(x.loc(i.a.type, True)), ] return code
def emit(self, inst, src, targ=None): '''emit the specified instruction with src as source operand and targ as the target operand. Handles requesting the operands from a non-local stack frame as necessary. using ebx or ecx is not allowed for either the src or targ. ''' #print inst, src, targ if isinstance(src, il.Symbol) and isinstance(targ, il.Symbol): raise Exception, 'Cannot emit an instruction with both source and target as symbols' elif isinstance(src, il.Symbol) and targ is None: if src.islocal(self.cfunc): return [ inst(x.loc(src.type)) ] return [ x.movl(x.cint(4*(src.scope_depth-1)), x.ebx), x.movl(x.static('display', x.ebx), x.ebx), inst(x.mem(x.ebx, src.type.offset)), ] elif not isinstance(src, il.Symbol) and targ is None: return [ inst(src), ] elif isinstance(src, il.Symbol) and targ is not None: if src.islocal(self.cfunc): return [ inst(x.loc(src.type), targ) ] return [ x.movl(x.cint(4*(src.scope_depth-1)), x.ebx), x.movl(x.static('display', x.ebx), x.ebx), inst(x.mem(x.ebx, src.type.offset), targ), ] elif isinstance(targ, il.Symbol): #print inst, src, targ, targ.type.basereg if targ.islocal(self.cfunc): return [ inst(src, x.loc(targ.type)) ] return [ x.movl(x.cint(4*(targ.scope_depth-1)), x.ebx), x.movl(x.static('display', x.ebx), x.ebx), x.movl(x.mem(x.ebx, targ.type.offset), x.ecx), inst(src, x.ecx), x.movl(x.ecx, x.mem(x.ebx, targ.type.offset)), ] else: return [ inst(src, targ) ]
def Iprm(self, i): if isinstance(i.b.type, il.Func): # this is a function param not a value code = [ x.leal(i.b.type.entry, x.eax), x.movl(x.eax, x.mem(x.esp, -(2+i.a)*4)), ] else: code = [ x.movl(x.loc(i.b.type), x.eax), x.movl(x.eax, x.mem(x.esp, -(2+i.a)*4)), ] return code
def emit(self, inst, src, targ=None): """emit the specified instruction with src as source operand and targ as the target operand. Handles requesting the operands from a non-local stack frame as necessary. using ebx or ecx is not allowed for either the src or targ. """ ## We have several choices to make in order to emit the right inst. ## (1) does the inst only refer to symbols local to the current scope? ## (a) if yes: emit the instruction with no changes ## (b) if no: detirmine what changes have to be made. ## (2) We now know the instruction is not local. One (but not both) of ## the symbols does not come from this stack frame. That means they ## have to be fetched from the appropriate stack frame. We detirmine ## the appropriate frame to fetch (or put) the sym from(to) by ## consulting the display. ## (3) The display is a static array: ## ## +------------+------------+------------+------------+ ## scope depth | 0 | 1 | 2 | 3 | ## +------------+------------+------------+------------+ ## frame address | 0x???????? | 0x???????? | 0x???????? | 0x???????? | ## +------------+------------+------------+------------+ ## ## The 'frame address' contains the address of the the stack frame ## most recently seen function. When that function returns it will ## update the display with the previous address it contained. When ## A new function is called at that scope depth a new address will ## be placed in the display and the old will be saved. ## ## (4) Therefore to get the non-local symbols we simply need to consult ## the display to find the appropriate frame. Each symbol knows what ## scope-depth it was declared at. ## ## NB: The symbols store there scope depths starting at 1. Therefore, in ## order to index into the display one must subtract 1 from the ## stored scope depth. ## ## NB: We multiply by 4 because each address is 4 bytes wide. if isinstance(src, il.Symbol) and isinstance(targ, il.Symbol): raise Exception, ("Cannot emit an instruction with both source and target as " "symbols") elif isinstance(src, il.Symbol) and targ is None: if src.islocal(self.cfunc): return [inst(x.loc(src.type))] return [ x.movl(x.cint(4 * (src.scope_depth - 1)), x.ebx), # compute the # index into the # display and # store in ebx x.movl(x.static("display", x.ebx), x.ebx), # get the non- # local stack # pointer and # store in ebx inst(x.mem(x.ebx, src.type.offset)), # emit the inst. ] elif not isinstance(src, il.Symbol) and targ is None: return [inst(src)] elif isinstance(src, il.Symbol) and targ is not None: if src.islocal(self.cfunc): return [inst(x.loc(src.type), targ)] return [ x.movl(x.cint(4 * (src.scope_depth - 1)), x.ebx), x.movl(x.static("display", x.ebx), x.ebx), inst(x.mem(x.ebx, src.type.offset), targ), ] elif isinstance(targ, il.Symbol): # print inst, src, targ, targ.type.basereg if targ.islocal(self.cfunc): return [inst(src, x.loc(targ.type))] return [ ## This version is slightly tricky we have to fetch and store ## the contents of the variable stored in the non-local stack ## frame. x.movl(x.cint(4 * (targ.scope_depth - 1)), x.ebx), x.movl(x.static("display", x.ebx), x.ebx), x.movl(x.mem(x.ebx, targ.type.offset), x.ecx), inst(src, x.ecx), x.movl(x.ecx, x.mem(x.ebx, targ.type.offset)), ] else: return [inst(src, targ)]
def Mv(self, i): code = [x.movl(x.loc(i.a.type), x.eax), x.movl(x.eax, x.loc(i.result.type))] return code
def Rprm(self, i): """Generate code for RPRM : Get a Return Param""" code = [x.movl(x.mem(x.esp, -(2 + i.a) * 4), x.eax), x.movl(x.eax, x.loc(i.result.type))] return code
def Gprm(self, i): """Generator code for GPRM : Get Input Param i""" code = [x.movl(x.mem(x.ebp, -(1 + i.a) * 4), x.eax), x.movl(x.eax, x.loc(i.result.type))] return code
def Gprm(self, i): code = [ x.movl(x.mem(x.ebp, -(1+i.a)*4), x.eax), x.movl(x.eax, x.loc(i.result.type)), ] return code