def xvariable_to_ast_lval(xv: X.XVariable, astree: AbstractSyntaxTree) -> AST.ASTLval: """Convert a CHIF variable to an AST Lval node.""" if xv.is_tmp: return astree.mk_temp_lval() elif xv.is_register_variable: xvden = cast("VRegisterVariable", xv.denotation) reg = xvden.register if reg.is_mips_register: mipsreg = cast("MIPSRegister", reg) name = "mips_" + mipsreg.name else: name = str(xv) return astree.mk_register_variable_lval(name) elif xv.is_memory_variable: xvmem = cast("VMemoryVariable", xv.denotation) return vmemory_variable_to_ast_lval(xvmem, astree) elif xv.is_auxiliary_variable: xvaux = cast("VAuxiliaryVariable", xv.denotation) return vauxiliary_variable_to_ast_lval(xvaux, astree) else: print("other: " + str(xv)) return astree.mk_variable_lval(str(xv))
def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[AST.ASTInstruction]: regsop = self.operands[1] if not regsop.is_register_list: raise UF.CHBError("Argument to push is not a register list") (splval, _, _) = self.operands[0].ast_lvalue(astree) (sprval, _, _) = self.operands[0].ast_rvalue(astree) instrs: List[AST.ASTInstruction] = [] registers = regsop.registers sp_incr = 4 * len(registers) sp_offset = 0 for r in registers: sp_offset_c = astree.mk_integer_constant(sp_offset) addr = astree.mk_binary_op("plus", sprval, sp_offset_c) lhs = astree.mk_variable_lval(r) rhs = astree.mk_memref_expr(addr) instrs.append(astree.mk_assign(lhs, rhs)) sp_offset += 4 sp_incr_c = astree.mk_integer_constant(sp_incr) sp_rhs = astree.mk_binary_op("plus", sprval, sp_incr_c) instrs.append(astree.mk_assign(splval, sp_rhs)) astree.add_instruction_span(instrs[0].id, iaddr, bytestring) return instrs
def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[AST.ASTInstruction]: rhs = XU.xxpr_to_ast_expr(xdata.xprs[1], astree) lhsvar = str(xdata.vars[0]) lhs = astree.mk_variable_lval(lhsvar) assign = astree.mk_assign(lhs, rhs) astree.add_instruction_span(assign.id, iaddr, bytestring) return [assign]
def stack_variable_to_ast_lval(offset: "VMemoryOffset", astree: AbstractSyntaxTree) -> AST.ASTLval: """TODO: split up.""" if offset.is_constant_value_offset: return astree.mk_stack_variable_lval(offset.offsetvalue()) print("stack variable: " + str(offset)) return astree.mk_variable_lval("stack: " + str(offset))
def assembly_ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[AST.ASTInstruction]: if len(xdata.vars) == 1 and len(xdata.xprs) == 1: lhs = astree.mk_variable_lval(str(xdata.vars[0])) rhs = XU.xxpr_to_ast_expr(xdata.xprs[0], astree) assign = astree.mk_assign(lhs, rhs) astree.add_instruction_span(assign.id, iaddr, bytestring) return [assign] else: return []
def global_variable_to_ast_lval(offset: "VMemoryOffset", astree: AbstractSyntaxTree) -> AST.ASTLval: if offset.is_constant_value_offset: gaddr = hex(offset.offsetvalue()) gvname = astree.global_variable_name(gaddr) if gvname is None: gvname = "gv_" + gaddr return astree.mk_global_variable_lval(gvname, globaladdress=int(gaddr, 16)) print("global-variable: " + "gv_" + str(offset)) return astree.mk_variable_lval("gv_" + str(offset))
def vmemory_variable_to_ast_lval(xvmem: "VMemoryVariable", astree: AbstractSyntaxTree) -> AST.ASTLval: """TODO: split up.""" if xvmem.base.is_local_stack_frame: return stack_variable_to_ast_lval(xvmem.offset, astree) elif xvmem.is_basevar_variable: return basevar_variable_to_ast_lval(xvmem.basevar, xvmem.offset, astree) elif xvmem.is_global_variable: return global_variable_to_ast_lval(xvmem.offset, astree) print("VMemoryVariable: " + str(xvmem) + " (" + xvmem.tags[0] + ")") return astree.mk_variable_lval(str(xvmem))
def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[AST.ASTInstruction]: (rhs1, _, _) = self.operands[0].ast_rvalue(astree) (rhs2, _, _) = self.operands[1].ast_rvalue(astree) lhs1 = str(xdata.vars[0]) lhs2 = str(xdata.vars[1]) if lhs1.endswith("[0]"): lhs1 = "*" + lhs1[:-3] lval1 = astree.mk_variable_lval(lhs1) lval2 = astree.mk_variable_lval(lhs2) assign1 = astree.mk_assign(lval1, rhs1) assign2 = astree.mk_assign(lval2, rhs2) astree.add_instruction_span(assign1.id, iaddr, bytestring) astree.add_instruction_span(assign2.id, iaddr, bytestring) return [assign1, assign2]
def basevar_variable_to_ast_lval(basevar: "X.XVariable", offset: "VMemoryOffset", astree: AbstractSyntaxTree) -> AST.ASTLval: if offset.is_constant_value_offset: offsetvalue = offset.offsetvalue() baselval = xvariable_to_ast_lval(basevar, astree) basetype = baselval.ctype if basetype is not None: if basetype.is_array: elttype = cast("BCTypArray", basetype).tgttyp eltsize = elttype.byte_size() index = offsetvalue // eltsize indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif basetype.is_pointer: tgttype = cast("BCTypPtr", basetype).tgttyp basexpr = astree.mk_lval_expr(baselval) if tgttype.is_scalar: tgtsize = tgttype.byte_size() index = offsetvalue // tgtsize indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif tgttype.is_struct: compinfo = cast("BCTypComp", tgttype).compinfo fieldoffset = field_at_offset(compinfo, offsetvalue, astree) return astree.mk_memref_lval(basexpr, fieldoffset) elif tgttype.is_void: index = offsetvalue indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) elif offsetvalue == 0: return astree.mk_memref_lval(basexpr) else: print(" -> Basevar with basetype") else: index = offsetvalue indexoffset = astree.mk_scalar_index_offset(index) return astree.mk_lval(baselval.lhost, indexoffset) print("Basevar_variable: " + str(basevar) + "; offset: " + str(offset)) return astree.mk_variable_lval(str(basevar) + str(offset))
def vauxiliary_variable_to_ast_lval(xvaux: "VAuxiliaryVariable", astree: AbstractSyntaxTree) -> AST.ASTLval: vconstvar = xvaux.auxvar if vconstvar.is_initial_register_value: vconstvar = cast("VInitialRegisterValue", vconstvar) return vinitregister_value_to_ast_lval(vconstvar, astree) elif vconstvar.is_initial_memory_value: vconstvar = cast("VInitialMemoryValue", vconstvar) return vinitmemory_value_to_ast_lval(vconstvar, astree) elif vconstvar.is_function_return_value: vconstvar = cast("VFunctionReturnValue", vconstvar) return vfunctionreturn_value_to_ast_lval(vconstvar, astree) print("VConstvar: " + vconstvar.tags[0] + " " + str(xvaux)) """TODO: split up.""" print("auxiliary variable: " + str(xvaux)) return astree.mk_variable_lval(str(xvaux))
def ast_lvalue( self, astree: AbstractSyntaxTree ) -> Tuple[AST.ASTLval, List[AST.ASTInstruction], List[AST.ASTInstruction]]: offset = self.memory_offset.ast_rvalue(astree) if not self.is_add: offset = astree.mk_unary_op("minus", offset) xreg = astree.mk_register_variable_expr(self.register) xindex = astree.mk_binary_op("plus", xreg, offset) if self.is_write_back: reglv = astree.mk_variable_lval(self.register) assign = astree.mk_assign(reglv, xindex) if self.is_index: memexp = astree.mk_memref_lval(xindex) return (memexp, [], [assign]) else: memexp = astree.mk_memref_lval(xreg) return (memexp, [], [assign]) else: memexp = astree.mk_memref_lval(xindex) return (memexp, [], [])
def ast_lvalue( self, astree: AbstractSyntaxTree ) -> Tuple[AST.ASTLval, List[AST.ASTInstruction], List[AST.ASTInstruction]]: return (astree.mk_variable_lval(self.register), [], [])