예제 #1
0
파일: binary.go 프로젝트: tsavola/wag
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)
}