Beispiel #1
0
 def InitCode(self):
     """The pre-amble to the generated code. Contains data and the _start
     label. Creates a new stack frame."""
     return [
         ".section .data",
         "printf_msg:",
         r'  .ascii "%d\n\0"',
         ## START DEBUG MESSAGES ##
         "push_msg:",
         r'  .ascii "push 0x%x\n\0"',
         "pop1_msg:",
         r'  .ascii "pop1 0x%x\n\0"',
         "pop2_msg:",
         r'  .ascii "pop2 0x%x\n\0"',
         ## END DEBUG MESSAGES ##
         ## The display stores the location of non-local stack frames
         ## see. def emit(...)
         "display:",
         r"  .long %s" % ", ".join("0" for x in xrange(self.table.max_depth)),
         "",
         ".section .text",
         ".global _start",
         x.label("_start"),
         x.movl(x.esp, x.ebp),
         x.movl(x.ebp, "0(%ebp)"),
         #'.global main',
         # x86.label('main'),
     ]
Beispiel #2
0
 def InitCode(self):
     return [
         '.section .data',
         'printf_msg:',
         r'  .ascii "%d\n\0"',
         'push_msg:',
         r'  .ascii "push 0x%x\n\0"',
         'pop1_msg:',
         r'  .ascii "pop1 0x%x\n\0"',
         'pop2_msg:',
         r'  .ascii "pop2 0x%x\n\0"',
         'display:',
         r'  .long %s' % ', '.join('0' for x in xrange(self.table.max_depth)),
         '',
         '.section .text',
         '.global _start',
         x.label('_start'),
         x.movl(x.esp, x.ebp),
         x.movl(x.ebp, '0(%ebp)'),
         #'.global main',
         #x86.label('main'),
     ]
Beispiel #3
0
    def Func(self, name, main=False):
        """Generates x86 code for the function given by name. This is the entry
        point for all code generation."""

        ## Get the function.
        func = self.functions[name]
        self.cfunc = func

        ## Generate a label for the function
        self.code += [x.label(name)]

        ## If this is not the `main` function generate a stack push
        if not main:
            self.code += self.FramePush(len(func.params), func.scope_depth)

        ## Move the stack pointer down. This creates the stack frame.
        syms = self.gather_syms(func.blks)
        sp_offset = self.place_symbols(syms, func)
        self.code += [x.subl(x.cint(sp_offset * 4), x.esp)]

        def block(insts):
            """Generate the x86 instruction for the given block of instructions.
            """

            ## We could do something more clever than switch case here, but I
            ## (for now) perfer the simplicity.
            for i in insts:
                if i.op == il.PRNT:
                    self.code += self.Print(i)
                elif i.op == il.IMM:
                    self.code += self.Imm(i)
                elif i.op == il.GPRM:
                    self.code += self.Gprm(i)
                elif i.op == il.IPRM:
                    self.code += self.Iprm(i)
                elif i.op == il.OPRM:
                    ## OPRMs always appear directly before RTRN instructions.
                    ## Based on the way the stack frame pop is generated the pop
                    ## must be generated before the OPRM instruction. So the
                    ## output params can be properly returned.
                    if not main and func.oparam_count > 0:
                        self.code += self.FramePop(len(func.params), func.scope_depth)
                    if func.oparam_count == 0:
                        raise Exception, "expected no return paramters got at least 1."
                    self.code += self.Oprm(i)
                elif i.op == il.RPRM:
                    self.code += self.Rprm(i)
                elif i.op == il.CALL:
                    self.code += self.Call(i)
                elif i.op == il.RTRN:
                    if not main and func.oparam_count == 0:
                        self.code += self.FramePop(len(func.params), func.scope_depth)
                    self.code += self.Return(i)
                elif i.op == il.MV:
                    self.code += self.Mv(i)
                elif i.op in [il.ADD, il.SUB, il.MUL, il.DIV]:
                    self.code += self.Op(i)
                elif i.op in [il.IFEQ, il.IFNE, il.IFLT, il.IFLE, il.IFGT, il.IFGE]:
                    self.code += self.BranchOp(i)
                elif i.op == il.J:
                    self.code += self.J(i)
                elif i.op == il.NOP:
                    self.code += self.Nop(i)
                else:
                    raise Exception, il.opsr[i.op]

        ## generate a label for the entry block of the function.
        self.code += [x.label(func.entry.name)]
        block(self.blocks[func.entry.name].insts)  # generate the function.

        ## for each block in the function (excluding entry and exit) generate
        ## the code.
        for b in func.blks:
            if b.name == func.entry.name:
                continue
            if b.name == func.exit.name:
                continue
            self.code += [x.label(b.name)]
            self.code += [x.nop()]
            block(self.blocks[b.name].insts)

        ## If there a distinct exit block, generate it.
        if func.entry.name != func.exit.name:
            self.code += [x.label(func.exit.name)]
            b = func.exit
            self.code += [x.nop()]
            block(self.blocks[b.name].insts)
Beispiel #4
0
    def Func(self, name, main=False):
        #print name
        self.code += [
            x.label(name)
        ]

        #print '->', insts
        func = self.functions[name]
        self.cfunc = func
        #insts = self.blocks[func.entry.name].insts

        self.bp_offset = 3

        if not main:
            self.code += self.FramePush(len(func.params), func.scope_depth)
        syms = self.gather_syms(func.blks)
        #print syms
        fp_offset = self.place_symbols(syms, func)
        #print name, 'fp_offset', fp_offset
        self.code += [
            x.subl(x.cint(fp_offset*4), x.esp)
            #(vm.IMM, 4, fp_offset, 'start func %s' % (name)),
            #(vm.ADD, 1, 4, 'fp offset add inst'),
        ]

        def block(insts):
            for i in insts:
                if i.op == il.PRNT:
                    self.code += self.Print(i)
                elif i.op == il.IMM:
                    self.code += self.Imm(i)
                elif i.op == il.GPRM:
                    self.code += self.Gprm(i)
                elif i.op == il.IPRM:
                    self.code += self.Iprm(i)
                elif i.op == il.OPRM:
                    if not main and func.oparam_count > 0:
                        self.code += self.FramePop(len(func.params), func.scope_depth)
                    if func.oparam_count == 0:
                        raise Exception, "expected no return paramters got at least 1."
                    self.code += self.Oprm(i)
                elif i.op == il.RPRM:
                    self.code += self.Rprm(i)
                elif i.op == il.CALL:
                    self.code += self.Call(i)
                elif i.op == il.RTRN:
                    if not main and func.oparam_count == 0:
                        self.code += self.FramePop(len(func.params), func.scope_depth)
                    self.code += self.Return(i)
                elif i.op == il.MV:
                    self.code += self.Mv(i)
                elif i.op in [il.ADD, il.SUB, il.MUL, il.DIV]:
                    self.code += self.Op(i)
                elif i.op in [il.IFEQ, il.IFNE, il.IFLT, il.IFLE, il.IFGT, il.IFGE]:
                    self.code += self.BranchOp(i)
                elif i.op == il.J:
                    self.code += self.J(i)
                elif i.op == il.NOP:
                    self.code += self.Nop(i)
                else:
                    raise Exception, il.opsr[i.op]
                #if i.label is not None:
                    #print code[l]
                    #code[l] = (code[l][0], code[l][1], code[l][2], i.label)
        self.code += [ x.label(func.entry.name) ]
        block(self.blocks[func.entry.name].insts)
        for b in func.blks:
            if b.name == func.entry.name: continue
            if b.name == func.exit.name: continue
            self.code += [ x.label(b.name) ]
            self.floc[b.name] = len(self.code)
            self.code += [ x.nop() ]
            block(self.blocks[b.name].insts)
        if func.entry.name != func.exit.name:
            self.code += [ x.label(func.exit.name) ]
            b = func.exit
            self.floc[b.name] = len(self.code)
            self.code += [ x.nop() ]
            block(self.blocks[b.name].insts)