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")
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_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 ## Iterate over this list twice ## - Emit the scalar result ## - Emit the vector result i=0 for regtype,regid,toss,numregs in regs: if (hex_common.is_written(regid)): if (not hex_common.is_hvx_reg(regtype)): 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 # Second pass for regtype,regid,toss,numregs in regs: if (hex_common.is_written(regid)): if (hex_common.is_hvx_reg(regtype)): gen_def_helper_opn(f, tag, regtype, regid, toss, numregs, i) 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)): if (hex_common.is_hvx_reg(regtype) and hex_common.is_readwrite(regid)): continue 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')