func (mach X86) binaryShiftOp(code gen.RegCoder, index uint8, a, b values.Operand) values.Operand { insn := binaryShiftInsns[index] var targetReg regs.R switch b.Storage { case values.Imm: targetReg, _ = mach.opMaybeResultReg(code, a, true) insn.imm.op(code, b.Type, targetReg, uint8(b.ImmValue())) default: if b.Storage.IsReg() && b.Reg() == regShiftCount { targetReg, _ = mach.opMaybeResultReg(code, a, false) defer code.Discard(b) } else { if code.RegAllocated(types.I32, regShiftCount) { targetReg, _ = mach.opMaybeResultReg(code, a, true) if targetReg == regShiftCount { Mov.opFromReg(code, a.Type, regResult, regShiftCount) targetReg = regResult defer code.FreeReg(types.I32, regShiftCount) } else { // unknown operand in regShiftCount Mov.opFromReg(code, types.I64, regScratch, regShiftCount) defer Mov.opFromReg(code, types.I64, regShiftCount, regScratch) } } else { code.AllocSpecificReg(types.I32, regShiftCount) defer code.FreeReg(types.I32, regShiftCount) targetReg, _ = mach.opMaybeResultReg(code, a, true) } b.Type = types.I32 // TODO: 8-bit mov mach.OpMove(code, regShiftCount, b, false) } insn.opReg(code, a.Type, targetReg) } return values.TempRegOperand(a.Type, targetReg, true) }