diff options
Diffstat (limited to 'src/arch/aarch64/Emit.zig')
| -rw-r--r-- | src/arch/aarch64/Emit.zig | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 077330f0ca..ac731636bd 100644 --- a/src/arch/aarch64/Emit.zig +++ b/src/arch/aarch64/Emit.zig @@ -162,6 +162,17 @@ pub fn emitMir( .push_regs => try emit.mirPushPopRegs(inst), .pop_regs => try emit.mirPushPopRegs(inst), + + .sbfx, + .ubfx, + => try emit.mirBitfieldExtract(inst), + + .sxtb, + .sxth, + .sxtw, + .uxtb, + .uxth, + => try emit.mirExtend(inst), } } } @@ -1050,3 +1061,32 @@ fn mirPushPopRegs(emit: *Emit, inst: Mir.Inst.Index) !void { else => unreachable, } } + +fn mirBitfieldExtract(emit: *Emit, inst: Mir.Inst.Index) !void { + const tag = emit.mir.instructions.items(.tag)[inst]; + const rr_lsb_width = emit.mir.instructions.items(.data)[inst].rr_lsb_width; + const rd = rr_lsb_width.rd; + const rn = rr_lsb_width.rn; + const lsb = rr_lsb_width.lsb; + const width = rr_lsb_width.width; + + switch (tag) { + .sbfx => try emit.writeInstruction(Instruction.sbfx(rd, rn, lsb, width)), + .ubfx => try emit.writeInstruction(Instruction.ubfx(rd, rn, lsb, width)), + else => unreachable, + } +} + +fn mirExtend(emit: *Emit, inst: Mir.Inst.Index) !void { + const tag = emit.mir.instructions.items(.tag)[inst]; + const rr = emit.mir.instructions.items(.data)[inst].rr; + + switch (tag) { + .sxtb => try emit.writeInstruction(Instruction.sxtb(rr.rd, rr.rn)), + .sxth => try emit.writeInstruction(Instruction.sxth(rr.rd, rr.rn)), + .sxtw => try emit.writeInstruction(Instruction.sxtw(rr.rd, rr.rn)), + .uxtb => try emit.writeInstruction(Instruction.uxtb(rr.rd, rr.rn)), + .uxth => try emit.writeInstruction(Instruction.uxth(rr.rd, rr.rn)), + else => unreachable, + } +} |
