def gen_helper_prototype(f, tag, tagregs, tagimms): regs = tagregs[tag] imms = tagimms[tag] numresults = 0 numscalarresults = 0 numscalarreadwrite = 0 for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): numresults += 1 if (hex_common.is_scalar_reg(regtype)): numscalarresults += 1 if (hex_common.is_readwrite(regid)): if (hex_common.is_scalar_reg(regtype)): numscalarreadwrite += 1 if (numscalarresults > 1): ## The helper is bogus when there is more than one result f.write('DEF_HELPER_1(%s, void, env)\n' % tag) else: ## Figure out how many arguments the helper will take if (numscalarresults == 0): def_helper_size = len(regs) + len(imms) + numscalarreadwrite + 1 if hex_common.need_part1(tag): def_helper_size += 1 if hex_common.need_slot(tag): def_helper_size += 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) ## The return type is void f.write(', void') else: def_helper_size = len(regs) + len(imms) + numscalarreadwrite if hex_common.need_part1(tag): def_helper_size += 1 if hex_common.need_slot(tag): def_helper_size += 1 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag)) ## Generate the qemu DEF_HELPER type for each result i = 0 for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 ## Put the env between the outputs and inputs f.write(', env') i += 1 ## Generate the qemu type for each input operand (regs and immediates) for regtype, regid, toss, numregs in regs: if (hex_common.is_read(regid)): gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 for immlett, bits, immshift in imms: f.write(", s32") ## Add the arguments for the instruction slot and part1 (if needed) if hex_common.need_slot(tag): f.write(', i32') if hex_common.need_part1(tag): f.write(' , i32') f.write(')\n')
def main(): hex_common.read_semantics_file(sys.argv[1]) hex_common.read_attribs_file(sys.argv[2]) tagregs = hex_common.get_tagregs() tagimms = hex_common.get_tagimms() with open(sys.argv[3], 'w') as f: for tag in hex_common.tags: regs = tagregs[tag] rregs = [] wregs = [] regids = "" for regtype, regid, toss, numregs in regs: if hex_common.is_read(regid): if regid[0] not in regids: regids += regid[0] rregs.append(regtype + regid + numregs) if hex_common.is_written(regid): wregs.append(regtype + regid + numregs) if regid[0] not in regids: regids += regid[0] for attrib in hex_common.attribdict[tag]: if hex_common.attribinfo[attrib]['rreg']: rregs.append(strip_reg_prefix(attribinfo[attrib]['rreg'])) if hex_common.attribinfo[attrib]['wreg']: wregs.append(strip_reg_prefix(attribinfo[attrib]['wreg'])) regids += calculate_regid_letters(tag) f.write('REGINFO(%s,"%s",\t/*RD:*/\t"%s",\t/*WR:*/\t"%s")\n' % \ (tag,regids,",".join(rregs),",".join(wregs))) for tag in hex_common.tags: imms = tagimms[tag] f.write('IMMINFO(%s' % tag) if not imms: f.write(''','u',0,0,'U',0,0''') for sign, size, shamt in imms: if sign == 'r': sign = 's' if not shamt: shamt = "0" f.write(''','%s',%s,%s''' % (sign, size, shamt)) if len(imms) == 1: if sign.isupper(): myu = 'u' else: myu = 'U' f.write(''','%s',0,0''' % myu) f.write(')\n')
def gen_tcg_func(f, tag, regs, imms): f.write("static void generate_%s(\n" % tag) f.write(" CPUHexagonState *env,\n") f.write(" DisasContext *ctx,\n") f.write(" Insn *insn,\n") f.write(" Packet *pkt)\n") f.write('{\n') if hex_common.need_ea(tag): gen_decl_ea_tcg(f, tag) i = 0 ## Declare all the operands (regs and immediates) for regtype, regid, toss, numregs in regs: genptr_decl_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 for immlett, bits, immshift in imms: genptr_decl_imm(f, immlett) if 'A_PRIV' in hex_common.attribdict[tag]: f.write(' fCHECKFORPRIV();\n') if 'A_GUEST' in hex_common.attribdict[tag]: f.write(' fCHECKFORGUEST();\n') ## Read all the inputs for regtype, regid, toss, numregs in regs: if (hex_common.is_read(regid)): genptr_src_read_opn(f, regtype, regid, tag) if (hex_common.skip_qemu_helper(tag)): f.write(" fGEN_TCG_%s(%s);\n" % (tag, hex_common.semdict[tag])) else: ## Generate the call to the helper for immlett, bits, immshift in imms: gen_helper_decl_imm(f, immlett) if hex_common.need_part1(tag): f.write(" TCGv part1 = tcg_const_tl(insn->part1);\n") if hex_common.need_slot(tag): f.write(" TCGv slot = tcg_const_tl(insn->slot);\n") f.write(" gen_helper_%s(" % (tag)) i = 0 ## If there is a scalar result, it is the return type for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 if (i > 0): f.write(", ") f.write("cpu_env") i = 1 for regtype, regid, toss, numregs in regs: if (hex_common.is_read(regid)): gen_helper_call_opn(f, tag, regtype, regid, toss, numregs, i) i += 1 for immlett, bits, immshift in imms: gen_helper_call_imm(f, immlett) if hex_common.need_slot(tag): f.write(", slot") if hex_common.need_part1(tag): f.write(", part1") f.write(");\n") if hex_common.need_slot(tag): f.write(" tcg_temp_free(slot);\n") if hex_common.need_part1(tag): f.write(" tcg_temp_free(part1);\n") for immlett, bits, immshift in imms: gen_helper_free_imm(f, immlett) ## Write all the outputs for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): genptr_dst_write_opn(f, regtype, regid, tag) ## Free all the operands (regs and immediates) if hex_common.need_ea(tag): gen_free_ea_tcg(f) for regtype, regid, toss, numregs in regs: genptr_free_opn(f, regtype, regid, i, tag) i += 1 f.write("}\n\n")
def gen_helper_function(f, tag, tagregs, tagimms): regs = tagregs[tag] imms = tagimms[tag] numresults = 0 numscalarresults = 0 numscalarreadwrite = 0 for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): numresults += 1 if (hex_common.is_scalar_reg(regtype)): numscalarresults += 1 if (hex_common.is_readwrite(regid)): if (hex_common.is_scalar_reg(regtype)): numscalarreadwrite += 1 if (numscalarresults > 1): ## The helper is bogus when there is more than one result f.write( "void HELPER(%s)(CPUHexagonState *env) { BOGUS_HELPER(%s); }\n" % (tag, tag)) else: ## The return type of the function is the type of the destination ## register (if scalar) i = 0 for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): if (hex_common.is_pair(regid)): if (hex_common.is_hvx_reg(regtype)): continue else: gen_helper_return_type_pair(f, regtype, regid, i) elif (hex_common.is_single(regid)): if (hex_common.is_hvx_reg(regtype)): continue else: gen_helper_return_type(f, regtype, regid, i) else: print("Bad register parse: ", regtype, regid, toss, numregs) i += 1 if (numscalarresults == 0): f.write("void") f.write(" HELPER(%s)(CPUHexagonState *env" % tag) ## Arguments include the vector destination operands i = 1 for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): if (hex_common.is_pair(regid)): if (hex_common.is_hvx_reg(regtype)): gen_helper_arg_ext_pair(f, regtype, regid, i) else: continue elif (hex_common.is_single(regid)): if (hex_common.is_hvx_reg(regtype)): gen_helper_arg_ext(f, regtype, regid, i) else: # This is the return value of the function continue else: print("Bad register parse: ", regtype, regid, toss, numregs) i += 1 ## Arguments to the helper function are the source regs and immediates for regtype, regid, toss, numregs in regs: if (hex_common.is_read(regid)): if (hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid)): continue gen_helper_arg_opn(f, regtype, regid, i, tag) i += 1 for immlett, bits, immshift in imms: gen_helper_arg_imm(f, immlett) i += 1 if hex_common.need_slot(tag): if i > 0: f.write(", ") f.write("uint32_t slot") i += 1 if hex_common.need_part1(tag): if i > 0: f.write(", ") f.write("uint32_t part1") f.write(")\n{\n") if (not hex_common.need_slot(tag)): f.write(" uint32_t slot __attribute__((unused)) = 4;\n") if hex_common.need_ea(tag): gen_decl_ea(f) ## Declare the return variable i = 0 for regtype, regid, toss, numregs in regs: if (hex_common.is_writeonly(regid)): gen_helper_dest_decl_opn(f, regtype, regid, i) i += 1 for regtype, regid, toss, numregs in regs: if (hex_common.is_read(regid)): if (hex_common.is_pair(regid)): if (hex_common.is_hvx_reg(regtype)): gen_helper_src_var_ext_pair(f, regtype, regid, i) elif (hex_common.is_single(regid)): if (hex_common.is_hvx_reg(regtype)): gen_helper_src_var_ext(f, regtype, regid) else: print("Bad register parse: ", regtype, regid, toss, numregs) if 'A_FPOP' in hex_common.attribdict[tag]: f.write(' arch_fpop_start(env);\n') f.write(" %s\n" % hex_common.semdict[tag]) if 'A_FPOP' in hex_common.attribdict[tag]: f.write(' arch_fpop_end(env);\n') ## Save/return the return variable for regtype, regid, toss, numregs in regs: if (hex_common.is_written(regid)): gen_helper_return_opn(f, regtype, regid, i) f.write("}\n\n")