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 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")