Exemplo n.º 1
0
        protected override void EmitImpl(Assembler a)
        {
            a.Comment = Comment;
            a.EmitOptions = _emitOptions;

            if (IsSpecial)
            {
                // ${SPECIAL_INSTRUCTION_HANDLING_BEGIN}
                switch (_code)
                {
                case InstructionCode.Cpuid:
                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.Cbw:
                case InstructionCode.Cdqe:
                case InstructionCode.Cwde:
                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.Cdq:
                case InstructionCode.Cqo:
                case InstructionCode.Cwd:
                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.Cmpxchg:
                    a.EmitInstruction(_code, _operands[1], _operands[2]);
                    return;

                case InstructionCode.Cmpxchg8b:
                case InstructionCode.Cmpxchg16b:
                    if (_code == InstructionCode.Cmpxchg16b && !Util.IsX64)
                        throw new NotSupportedException(string.Format("The '{0}' instruction is only supported on X64.", _code));

                    a.EmitInstruction(_code, _operands[4]);
                    return;

                case InstructionCode.Daa:
                case InstructionCode.Das:
                    if (!Util.IsX86)
                        throw new NotSupportedException(string.Format("The '{0}' instruction is only supported on X86.", _code));

                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.Imul:
                case InstructionCode.Mul:
                case InstructionCode.Idiv:
                case InstructionCode.Div:
                    // INST dst_lo (implicit), dst_hi (implicit), src (explicit)
                    if (_operands.Length != 3)
                        throw new NotSupportedException();

                    a.EmitInstruction(_code, _operands[2]);
                    return;

                case InstructionCode.MovPtr:
                    break;

                case InstructionCode.Lahf:
                case InstructionCode.Sahf:
                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.Maskmovdqu:
                case InstructionCode.Maskmovq:
                    a.EmitInstruction(_code, _operands[1], _operands[2]);
                    return;

                case InstructionCode.Enter:
                case InstructionCode.Leave:
                    // TODO: SPECIAL INSTRUCTION.
                    break;

                case InstructionCode.Ret:
                    // TODO: SPECIAL INSTRUCTION.
                    break;

                case InstructionCode.Monitor:
                case InstructionCode.Mwait:
                    // TODO: MONITOR/MWAIT (COMPILER).
                    break;

                case InstructionCode.Pop:
                case InstructionCode.Popad:
                case InstructionCode.Popfd:
                case InstructionCode.Popfq:
                    // TODO: SPECIAL INSTRUCTION.
                    break;

                case InstructionCode.Push:
                case InstructionCode.Pushad:
                case InstructionCode.Pushfd:
                case InstructionCode.Pushfq:
                    // TODO: SPECIAL INSTRUCTION.
                    break;

                case InstructionCode.Rcl:
                case InstructionCode.Rcr:
                case InstructionCode.Rol:
                case InstructionCode.Ror:
                case InstructionCode.Sal:
                case InstructionCode.Sar:
                case InstructionCode.Shl:
                case InstructionCode.Shr:
                    a.EmitInstruction(_code, _operands[0], Register.cl);
                    return;

                case InstructionCode.Shld:
                case InstructionCode.Shrd:
                    a.EmitInstruction(_code, _operands[0], _operands[1], Register.cl);
                    return;

                case InstructionCode.Rdtsc:
                case InstructionCode.Rdtscp:
                    a.EmitInstruction(_code);
                    return;

                case InstructionCode.RepLodsb:
                case InstructionCode.RepLodsd:
                case InstructionCode.RepLodsq:
                case InstructionCode.RepLodsw:
                case InstructionCode.RepMovsb:
                case InstructionCode.RepMovsd:
                case InstructionCode.RepMovsq:
                case InstructionCode.RepMovsw:
                case InstructionCode.RepStosb:
                case InstructionCode.RepStosd:
                case InstructionCode.RepStosq:
                case InstructionCode.RepStosw:
                case InstructionCode.RepeCmpsb:
                case InstructionCode.RepeCmpsd:
                case InstructionCode.RepeCmpsq:
                case InstructionCode.RepeCmpsw:
                case InstructionCode.RepeScasb:
                case InstructionCode.RepeScasd:
                case InstructionCode.RepeScasq:
                case InstructionCode.RepeScasw:
                case InstructionCode.RepneCmpsb:
                case InstructionCode.RepneCmpsd:
                case InstructionCode.RepneCmpsq:
                case InstructionCode.RepneCmpsw:
                case InstructionCode.RepneScasb:
                case InstructionCode.RepneScasd:
                case InstructionCode.RepneScasq:
                case InstructionCode.RepneScasw:
                    a.EmitInstruction(_code);
                    return;

                default:
                    throw new CompilerException("Instruction is marked as special but no handling for it was present.");
                }
                // ${SPECIAL_INSTRUCTION_HANDLING_END}
            }

            switch (_operands.Length)
            {
            case 0:
                a.EmitInstruction(_code);
                break;
            case 1:
                a.EmitInstruction(_code, _operands[0]);
                break;
            case 2:
                a.EmitInstruction(_code, _operands[0], _operands[1]);
                break;
            case 3:
                a.EmitInstruction(_code, _operands[0], _operands[1], _operands[2]);
                break;
            default:
                throw new NotSupportedException();
            }
        }