def _InsRewriteOutOfBoundsImmediates(ins: ir.Ins, fun: ir.Fun, unit: ir.Unit) -> Optional[List[ir.Ins]]: if ins.opcode in isel_tab.OPCODES_REQUIRING_SPECIAL_HANDLING: return None inss = [] mismatches = isel_tab.FindtImmediateMismatchesInBestMatchPattern(ins, True) assert mismatches != isel_tab.MATCH_IMPOSSIBLE, f"could not match opcode {ins} {ins.operands}" if mismatches == 0: return None for pos in range(o.MAX_OPERANDS): if mismatches & (1 << pos) != 0: const_kind = ins.operands[pos].kind if const_kind is o.DK.F32 or const_kind is o.DK.F64: inss += lowering.InsEliminateImmediateViaMem( ins, pos, fun, unit, o.DK.A32, o.DK.U32) else: inss.append(lowering.InsEliminateImmediateViaMov( ins, pos, fun)) if not inss: return None # assert len(inss) == 1, f"unexpected rewrites for {ins.opcode} {ins.operands} {len(inss)}" inss.append(ins) return inss
def _InsRewriteOutOfBoundsImmediates(ins: ir.Ins, fun: ir.Fun) -> Optional[List[ir.Ins]]: if ins.opcode in _OPCODES_IGNORED_BY_IMMEDIATE_REWRITER: return None inss = [] mismatches = isel_tab.FindtImmediateMismatchesInBestMatchPattern(ins) assert mismatches != isel_tab.MATCH_IMPOSSIBLE, f"could not match opcode {ins} {ins.operands}" if mismatches == 0: return None for pos in range(o.MAX_OPERANDS): if mismatches & (1 << pos) != 0: inss.append(lowering.InsEliminateImmediate(ins, pos, fun)) if not inss: return None # assert len(inss) == 1, f"unexpected rewrites for {ins.opcode} {ins.operands} {len(inss)}" inss.append(ins) return inss
def HandleIns(ins: ir.Ins, ctx: regs.EmitContext): print("INS: " + serialize.InsRenderToAsm(ins).strip() + f" [{' '.join(OpTypeStr(o) for o in ins.operands)}]") if ins.opcode in isel_tab.OPCODES_REQUIRING_SPECIAL_HANDLING: print(f" SPECIAL") return mismatches = isel_tab.FindtImmediateMismatchesInBestMatchPattern(ins) if mismatches == isel_tab.MATCH_IMPOSSIBLE: print(f" MATCH_IMPOSSIBLE") elif mismatches != 0: pattern = isel_tab.FindMatchingPattern(ins) assert pattern is None print(f" mismatches: {mismatches:x}") else: pattern = isel_tab.FindMatchingPattern(ins) print( f"PAT: reg:[{' '.join(a.name for a in pattern.type_constraints)}] " f"imm:[{' '.join(a.name for a in pattern.imm_constraints)}]") for tmpl in pattern.emit: armins = tmpl.MakeInsFromTmpl(ins, ctx) print(f" {disassembler.RenderInstructionSystematic(armins)}")
def _InsRewriteOutOfBoundsOffsetsStk(ins: ir.Ins, fun: ir.Fun) -> Optional[List[ir.Ins]]: # Note, we can handle any LEA_STK as long as it is adding a constant if ins.opcode not in {o.LD_STK, o.ST_STK}: return None mismatches = isel_tab.FindtImmediateMismatchesInBestMatchPattern(ins) assert mismatches != isel_tab.MATCH_IMPOSSIBLE, f"could not match opcode {ins} {ins.operands}" if mismatches == 0: return None inss = [] tmp = fun.GetScratchReg(o.DK.A32, "imm_stk", False) if ins.opcode is o.ST_STK: # note we do not have to worry about ins.operands[2] being Const # because those were dealt with by FunEliminateImmediateStores assert mismatches == (1 << 1) if isinstance(ins.operands[1], ir.Const): inss.append( ir.Ins(o.LEA_STK, [tmp, ins.operands[0], ins.operands[1]])) ins.Init(o.ST, [tmp, _ZERO_OFFSET, ins.operands[2]]) else: inss.append(ir.Ins(o.LEA_STK, [tmp, ins.operands[0], _ZERO_OFFSET])) ins.Init(o.ST, [tmp, ins.operands[1], ins.operands[2]]) else: assert ins.opcode is o.LD_STK assert mismatches & (1 << 2) if isinstance(ins.operands[2], ir.Const): inss.append( ir.Ins(o.LEA_STK, [tmp, ins.operands[1], ins.operands[2]])) ins.Init(o.LD, [ins.operands[0], tmp, _ZERO_OFFSET]) else: inss.append(ir.Ins(o.LEA_STK, [tmp, ins.operands[1], _ZERO_OFFSET])) ins.Init(o.LD, [ins.operands[0], tmp, ins.operands[2]]) inss.append(ins) return inss