def get_global_denotation( self, gvinfo: AST.ASTVarInfo, gaddr: str, offset: AST.ASTOffset) -> Tuple[AST.ASTVariable, AST.ASTOffset]: addr = int(gaddr, 16) if gvinfo.is_struct: compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo ioffset = addr - gvinfo.global_address fieldoffsets = compinfo.fieldoffsets() prevfinfo: Optional["BCFieldInfo"] = None prevoffset = -1 for (foffset, finfo) in fieldoffsets: if ioffset == foffset: id = self.new_id() var = AST.ASTVariable(id, gvinfo) if finfo.fieldtype.is_array: offset = self.mk_scalar_index_offset(0, offset) offset = self.mk_field_offset(finfo.fieldname, finfo.fieldtype, offset) return (var, offset) elif ioffset > foffset: prevfinfo = finfo prevoffset = foffset else: if prevfinfo is None: raise Exception("Offset mismatch") if prevfinfo.fieldtype.is_array: ftype = cast("BCTypArray", prevfinfo.fieldtype) eltsize = ftype.tgttyp.byte_size() aoffset = ioffset - prevoffset if aoffset % eltsize == 0: aindex = aoffset // eltsize offset = self.mk_scalar_index_offset( aindex, offset) else: raise Exception("Offset mismatch") id = self.new_id() var = AST.ASTVariable(id, gvinfo) offset = self.mk_field_offset(prevfinfo.fieldname, prevfinfo.fieldtype, offset) return (var, offset) else: name = "gv_" + gaddr return (self.mk_global_variable(name, globaladdress=int( gaddr, 16)), offset) else: name = "gv_" + gaddr return (self.mk_global_variable(name, globaladdress=int(gaddr, 16)), offset) else: id = self.new_id() var = AST.ASTVariable(id, gvinfo) return (var, offset)
def mk_temp_lval(self) -> AST.ASTLval: tmpname = "temp" + str(self.new_tmp_id()) varinfo = self.get_symbol(tmpname, None, None, None, None) id = self.new_id() var = AST.ASTVariable(id, varinfo) id = self.new_id() return AST.ASTLval(id, var, AST.ASTNoOffset(-1))
def mk_global_variable( self, name: str, vtype: Optional["BCTyp"] = None, globaladdress: Optional[int] = None) -> AST.ASTVariable: id = self.new_id() varinfo = self.get_symbol(name, vtype, None, None, globaladdress) return AST.ASTVariable(id, varinfo)
def get_struct_field_address(self, gaddr: int) -> AST.ASTExpr: gvname: Optional[str] = None gvinfo: Optional[AST.ASTVarInfo] = None for ((name, _), vinfo) in self.symboltable.items(): if vinfo.is_struct and vinfo.is_global: compinfo = (cast("BCTypComp", vinfo.vtype)).compinfo gvaddr = vinfo.global_address gvextent = gvaddr + compinfo.byte_size() if gaddr >= gvaddr and gaddr < gvextent: gvname = name gvinfo = vinfo break if gvname and gvinfo: compinfo = (cast("BCTypComp", gvinfo.vtype)).compinfo ioffset = gaddr - gvinfo.global_address fieldoffsets = compinfo.fieldoffsets() prevfinfo: Optional["BCFieldInfo"] = None prevoffset = -1 if ioffset == 0: id = self.new_id() var = AST.ASTVariable(id, gvinfo) lval = self.mk_lval(var, AST.ASTNoOffset(-1)) return self.mk_address_of(lval) for (foffset, finfo) in fieldoffsets: if ioffset == foffset: id = self.new_id() var = AST.ASTVariable(id, gvinfo) offset = self.mk_field_offset(finfo.fieldname, finfo.fieldtype, AST.ASTNoOffset(-1)) lval = self.mk_lval(var, offset) if finfo.fieldtype.is_array: return self.mk_lval_expr(lval) else: return self.mk_address_of(lval) raise Exception("Struct field not found for address " + hex(gaddr))
def mk_returnval_variable(self, iaddr: str, vtype: Optional["BCTyp"]) -> AST.ASTVariable: id = self.new_id() name = "rtn_" + iaddr altname = self.other_variable_name(name) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, None, None) else: varinfo = self.get_symbol(name, vtype, altname, None, None) return AST.ASTVariable(id, varinfo)
def mk_register_variable( self, name: str, vtype: Optional["BCTyp"] = None, parameter: Optional[int] = None) -> AST.ASTVariable: id = self.new_id() altname = self.register_variable_name(name) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, parameter, None) else: varinfo = self.get_symbol(name, vtype, altname, parameter, None) return AST.ASTVariable(id, varinfo)
def mk_stack_variable(self, offset: int) -> AST.ASTVariable: id = self.new_id() if offset < 0: name = "localvar_" + str(-offset) elif offset == 0: name = "localvar_0" else: name = "argvar_" + str(offset) altname = self.stack_variable_name(offset) if (altname and self.has_functiondef() and self.functiondef.has_localvar(altname)): localvinfo = self.functiondef.localvar(altname) varinfo = self.get_symbol(name, localvinfo.vtype, altname, None, None) else: varinfo = self.get_symbol(name, None, altname, None, None) return AST.ASTVariable(id, varinfo)
def mk_ignored_lval(self) -> AST.ASTLval: varinfo = ignoredvariable var = AST.ASTVariable(-1, varinfo) return AST.ASTLval(-1, var, AST.ASTNoOffset(-1))
def mk_variable(self, name: str) -> AST.ASTVariable: id = self.new_id() altname = self.other_variable_name(name) varinfo = self.get_symbol(name, None, altname, None, None) return AST.ASTVariable(id, varinfo)