Skip to content
Snippets Groups Projects
SMPDataFlowAnalysis.cpp 215 KiB
Newer Older
clc5q's avatar
clc5q committed
			SegRegPrefix = false;
		}
#if STARS_SPARK_EMIT_SEGMENT_REGS
clc5q's avatar
clc5q committed
		else {
			(void) SMP_strncat(OutString, "X86.", STARS_MAXSTR-1);
			(void) SMP_strncat(OutString, MDGetRegNumName(SegReg, RegSizes[SegReg]), STARS_MAXSTR-1);
	if (ScaleFactor > 0) {
		ScaleFactor = 1 << (ScaleFactor - 1);
		(void) SMP_snprintf(ScaleString, 4, "%d", ScaleFactor);
	}

#if STARS_SPARK_EMIT_SEGMENT_REGS
clc5q's avatar
clc5q committed
		if (SegRegPrefix) {
			(void) SMP_strncat(OutString, " + ", STARS_MAXSTR-1);
		if (!(UseSavedStackPtr && (BaseReg == MD_STACK_POINTER_REG))) {
			(void) SMP_strncat(OutString, "X86.", STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, MDGetRegNumName((STARS_regnum_t)BaseReg, ByteWidth), STARS_MAXSTR - 1);
		}
		else {
			(void) SMP_strncat(OutString, "SaveStackPtr", STARS_MAXSTR - 1);
		}
		if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
			++SubwordAddressRegCount;
		}
		if (IndexReg != STARS_x86_R_none) {
			(void) SMP_strncat(OutString, " + ", STARS_MAXSTR - 1);
			if (!(UseSavedStackPtr && (IndexReg == MD_STACK_POINTER_REG))) {
				(void) SMP_strncat(OutString, "X86.", STARS_MAXSTR - 1);
				(void) SMP_strncat(OutString, MDGetRegNumName((STARS_regnum_t) IndexReg, ByteWidth), STARS_MAXSTR - 1);
			}
			else {
				(void) SMP_strncat(OutString, "SaveStackPtr", STARS_MAXSTR - 1);
			}
			if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
				++SubwordAddressRegCount;
			}
				(void) SMP_strncat(OutString, "*", STARS_MAXSTR-1);
				(void) SMP_strncat(OutString, ScaleString, STARS_MAXSTR-1);
	else if (IndexReg != STARS_x86_R_none) {
#if STARS_SPARK_EMIT_SEGMENT_REGS
clc5q's avatar
clc5q committed
		if (SegRegPrefix) {
			(void) SMP_strncat(OutString, " + ", STARS_MAXSTR-1);
		if (!(UseSavedStackPtr && (IndexReg == MD_STACK_POINTER_REG))) {
			(void)SMP_strncat(OutString, "X86.", STARS_MAXSTR - 1);
			(void)SMP_strncat(OutString, MDGetRegNumName((STARS_regnum_t)IndexReg, ByteWidth), STARS_MAXSTR - 1);
		}
		else {
			(void)SMP_strncat(OutString, "SaveStackPtr", STARS_MAXSTR - 1);
		}
		if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
			++SubwordAddressRegCount;
		}
			(void) SMP_strncat(OutString, "*", STARS_MAXSTR-1);
			(void) SMP_strncat(OutString, ScaleString, STARS_MAXSTR-1);
clc5q's avatar
clc5q committed
	else if (!SegRegPrefix) {
		SMP_msg("ERROR: No BaseReg, no IndexReg in SIB\n");
	}
clc5q's avatar
clc5q committed
	if (!HasOffset) // can close the parens around regs
		(void) SMP_strncat(OutString, ")", STARS_MAXSTR-1);
	SMP_fprintf(OutFile, " %s", OutString);
clc5q's avatar
clc5q committed
	return;
void SPARKAnnotSIBToString(const STARSOpndTypePtr &Opnd, bool HasOffset, std::string &OutString, STARS_regnum_t SegReg, bool UseFP, bool Has64BitAddressing, bool UseSavedStackPtr) {
clc5q's avatar
clc5q committed
	int BaseReg;
	int IndexReg;
	uint16_t ScaleFactor;
	uint16_t ByteWidth = Opnd->GetByteWidth();
	STARS_ea_t offset;
	char OutString2[STARS_MAXSTR] = { '(', '\0' };
	char ScaleString[4];

clc5q's avatar
clc5q committed
		ByteWidth = 8;

	MDExtractAddressFields(Opnd, BaseReg, IndexReg, ScaleFactor, offset);

	bool SegRegPrefix = STARS_x86_is_segreg((int)SegReg);
	if (SegRegPrefix) {
		// Emit segment register string unless it is just the stack segment plus a stack operand,
		//  where the stack segment is implied anyway.
		if ((SegReg == STARS_x86_R_ss) && MDIsStackAccessOpnd(Opnd, UseFP)) {
			SegRegPrefix = false;
		}
#if STARS_SPARK_EMIT_SEGMENT_REGS
		else {
			(void)SMP_strncat(OutString2, "X86.", STARS_MAXSTR - 1);
			(void)SMP_strncat(OutString2, MDGetRegNumName(SegReg, RegSizes[SegReg]), STARS_MAXSTR - 1);
		}
#endif
	}

	if (ScaleFactor > 0) {
clc5q's avatar
clc5q committed
		(void) SMP_snprintf(ScaleString, 4, "%d", ScaleFactor);
	}

	if (BaseReg != STARS_x86_R_none) {
#if STARS_SPARK_EMIT_SEGMENT_REGS
		if (SegRegPrefix) {
			(void) SMP_strncat(OutString2, " + ", STARS_MAXSTR - 1);
		}
#endif
		if (!(UseSavedStackPtr && (BaseReg == MD_STACK_POINTER_REG))) {
			(void) SMP_strncat(OutString2, "X86.", STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString2, MDGetRegNumName((STARS_regnum_t)BaseReg, ByteWidth), STARS_MAXSTR - 1);
		}
		else {
			(void) SMP_strncat(OutString2, "SaveStackPtr", STARS_MAXSTR - 1);
		}
clc5q's avatar
clc5q committed
		if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
			++SubwordAddressRegCount;
		}
		if (IndexReg != STARS_x86_R_none) {
			if (!(UseSavedStackPtr && (IndexReg == MD_STACK_POINTER_REG))) {
				(void) SMP_strncat(OutString2, " + X86.", STARS_MAXSTR - 1);
				(void) SMP_strncat(OutString2, MDGetRegNumName((STARS_regnum_t)IndexReg, ByteWidth), STARS_MAXSTR - 1);
			}
			else {
				(void) SMP_strncat(OutString2, " + SaveStackPtr", STARS_MAXSTR - 1);
			}
clc5q's avatar
clc5q committed
			if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
				++SubwordAddressRegCount;
			}
			if (ScaleFactor > 0) {
				(void) SMP_strncat(OutString2, "*", STARS_MAXSTR - 1);
				(void) SMP_strncat(OutString2, ScaleString, STARS_MAXSTR - 1);
			}
		}
	}
	else if (IndexReg != STARS_x86_R_none) {
#if STARS_SPARK_EMIT_SEGMENT_REGS
		if (SegRegPrefix) {
			(void) SMP_strncat(OutString2, " + ", STARS_MAXSTR - 1);
		}
#endif
		if (!(UseSavedStackPtr && (IndexReg == MD_STACK_POINTER_REG))) {
			(void)SMP_strncat(OutString2, "X86.", STARS_MAXSTR - 1);
			(void)SMP_strncat(OutString2, MDGetRegNumName((STARS_regnum_t) IndexReg, ByteWidth), STARS_MAXSTR - 1);
		}
		else {
			(void)SMP_strncat(OutString2, "SaveStackPtr", STARS_MAXSTR - 1);
		}
clc5q's avatar
clc5q committed
		if (global_STARS_program->GetSTARS_ISA_Bytewidth() > ByteWidth) {
			++SubwordAddressRegCount;
		}
		if (ScaleFactor > 0) {
			(void) SMP_strncat(OutString2, "*", STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString2, ScaleString, STARS_MAXSTR - 1);
		}
	}
	else if (!SegRegPrefix) {
		SMP_msg("ERROR: No BaseReg, no IndexReg in SIB\n");
	}
	if (!HasOffset) // can close the parens around regs
		(void) SMP_strncat(OutString2, ")", STARS_MAXSTR - 1);
	OutString.assign(OutString2);
	return;
} // end of SPARKAnnotSIBToString()

// Debug: print one operand from an instruction or DEF or USE list.
void PrintOneOperand(const STARSOpndTypePtr &Opnd, uint32_t features, int OpNum) { 
	if ((nullptr != Opnd) && (!Opnd->IsVoidOp())) {
		PrintOperand(Opnd);
		PrintDefUse(features, OpNum);
	}
	return;
} // end of PrintOneOperand()

// Debug: print one operand.
void PrintOperand(const STARSOpndTypePtr &Opnd) { 
	if ((nullptr == Opnd) || (Opnd->IsVoidOp()))
	else if (Opnd->IsStaticMemOp()) {
		SMP_msg(" Operand: memory : addr: %lx", (unsigned long) Opnd->GetAddr());
		if (Opnd->HasSIBByte()) {
	else if (Opnd->IsMemNoDisplacementOp()) {
		if (Opnd->HasSIBByte()) { // has SIB info
			PrintSIB(Opnd);
		}
		else { // no SIB info
			STARS_regnum_t BaseReg = Opnd->GetReg();
		if (Opnd->GetAddr() != 0) {
			SMP_msg(" \n ERROR: addr for o_phrase type: %lx\n", (unsigned long) Opnd->GetAddr());
	else if (Opnd->IsMemDisplacementOp()) {
		STARS_ea_t offset = Opnd->GetAddr();
		int SignedOffset = (int) offset;
			SMP_msg(" displ %d", SignedOffset);
			STARS_regnum_t BaseReg = Opnd->GetReg();
			SMP_msg(" reg %s displ %d", RegNames[BaseReg], SignedOffset);
		SMP_msg(" Operand: register %s", MDGetRegName(Opnd));
	else if (Opnd->IsImmedOp()) {
		SMP_msg(" Operand: immed %ld", (long) Opnd->GetImmedValue());
	}
	else if (Opnd->IsFarPointer()) {
		SMP_msg(" Operand: FarPtrImmed addr: %lx", (unsigned long) Opnd->GetAddr());
	else if (Opnd->IsNearPointer()) {
		SMP_msg(" Operand: NearPtrImmed addr: %lx", (unsigned long) Opnd->GetAddr());
	else if (Opnd->IsTestRegOp()) {
		SMP_msg(" Operand: TestReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsDebugRegOp()) {
		SMP_msg(" Operand: DebugReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsControlRegOp()) {
		SMP_msg(" Operand: ControlReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsFloatingPointRegOp()) {
		SMP_msg(" Operand: FloatReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsMMXRegOp()) {
		SMP_msg(" Operand: MMXReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsXMMRegOp()) {
		SMP_msg(" Operand: XMMReg reg: %d", Opnd->GetReg());
	else if (Opnd->IsYMMRegOp()) {
		SMP_msg(" Operand: YMMReg reg: %d", Opnd->GetReg());
clc5q's avatar
clc5q committed
#if STARS_DEBUG_DUMP_IDENTIFY_HIDDEN_OPERANDS
clc5q's avatar
clc5q committed
#endif
} // end of PrintOperand()

// Print an operand that has no features flags or operand position number, such
//  as the op_t types found in lists and sets throughout the blocks, phi functions, etc.
void PrintListOperand(const STARSOpndTypePtr &Opnd, int SSANum) {
	if ((nullptr != Opnd) && (!Opnd->IsVoidOp())) {
		PrintOperand(Opnd);
		if (!Opnd->IsImmedOp()) {
			SMP_msg(" SSANum: %d ", SSANum);
		}
		else {
			SMP_msg(" ");
		}
} // end of PrintListOperand()

// Annotations: concisely print one operand to OutFile.
void AnnotPrintOperand(const STARSOpndTypePtr &Opnd, FILE *OutFile, bool UseFP, bool Has64BitAddressing) {
	char OutString[STARS_MAXSTR] = { '\0', '\0' };
	uint16_t ByteWidth = Opnd->GetByteWidth();
	STARS_regnum_t SegReg = Opnd->GetSegReg();
	bool SegRegPrefix = STARS_x86_is_segreg((int) SegReg);
	if (SegRegPrefix) {
		// Emit segment register string unless it is just the stack segment plus a stack operand,
		//  where the stack segment is implied anyway.
		if ((SegReg == STARS_x86_R_ss) && MDIsStackAccessOpnd(Opnd, UseFP)) {
			SegRegPrefix = false;
		}
		else if (SegReg != STARS_x86_R_ds) { // not default data segment 
			(void) SMP_strncat(OutString, MDGetRegNumName(SegReg, RegSizes[SegReg]), STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, ":", STARS_MAXSTR - 1);
		}
	}
		SMP_snprintf(OutString, STARS_MAXSTR - 1, " %llx", (unsigned long long) Opnd->GetAddr());
			AnnotPrintSIB(Opnd, false, OutFile, OutString, Has64BitAddressing);
		}
		else {
			SMP_fprintf(OutFile, " %s", OutString);
	else if (Opnd->IsMemNoDisplacementOp()) {
		if (Opnd->HasSIBByte()) { // has SIB info
			AnnotPrintSIB(Opnd, false, OutFile, OutString, Has64BitAddressing);
			STARS_regnum_t BaseReg = Opnd->GetReg();
			SMP_fprintf(OutFile, " [%s]", MDGetRegNumName(BaseReg, ByteWidth));
			SMP_msg(" \n ERROR: addr for o_phrase type: %llx\n", (unsigned long long) Opnd->GetAddr());
	else if (Opnd->IsMemDisplacementOp()) {
		STARS_ea_t offset = Opnd->GetAddr();
			AnnotPrintSIB(Opnd, (SignedOffset != 0), OutFile, OutString, Has64BitAddressing);
			if (SignedOffset > 0) // print plus sign
			else if (SignedOffset < 0) // minus sign will print automatically
			STARS_regnum_t BaseReg = Opnd->GetReg();
			if (SignedOffset >= 0) // print plus sign
				SMP_fprintf(OutFile, " [%s+%d]", MDGetRegNumName(BaseReg, ByteWidth), SignedOffset);
			else // minus sign will print automatically
				SMP_fprintf(OutFile, " [%s%d]", MDGetRegNumName(BaseReg, ByteWidth), SignedOffset);
		SMP_fprintf(OutFile, " %s", MDGetRegName(Opnd));
	else if (Opnd->IsImmedOp()) {
		SMP_fprintf(OutFile, " %ld", (long) Opnd->GetImmedValue());
	else if ((Opnd->IsFarPointer()) || (Opnd->IsNearPointer())) {
		SMP_fprintf(OutFile, " %llx", (unsigned long long) Opnd->GetAddr());
// Annotations: concisely print one operand to a string.
void StringPrintOperand(const STARSOpndTypePtr &Opnd, string &OutStream, bool UseFP, bool Has64BitAddressing) {
	char OutString[STARS_MAXSTR] = { '\0', '\0' };
	char DummyBuf[STARS_MAXSTR] = { '\0', '\0' };
	uint16_t ByteWidth = Opnd->GetByteWidth();
	if (Has64BitAddressing)
		ByteWidth = 8;

	STARS_regnum_t SegReg = Opnd->GetSegReg();
	bool SegRegPrefix = STARS_x86_is_segreg((int)SegReg);
	if (SegRegPrefix) {
		// Emit segment register string unless it is just the stack segment plus a stack operand,
		//  where the stack segment is implied anyway.
		if ((SegReg == STARS_x86_R_ss) && MDIsStackAccessOpnd(Opnd, UseFP)) {
			SegRegPrefix = false;
		}
		else if (SegReg != STARS_x86_R_ds) { // not default data segment 
			(void) SMP_strncat(OutString, MDGetRegNumName(SegReg, RegSizes[SegReg]), STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, ":", STARS_MAXSTR - 1);
		}
	}

	if (Opnd->IsStaticMemOp()) {
		SMP_snprintf(OutString, STARS_MAXSTR - 1, " %llx", (unsigned long long) Opnd->GetAddr());
		if (Opnd->HasSIBByte()) {
			StringPrintSIB(Opnd, false, OutString, Has64BitAddressing);
		}
	}
	else if (Opnd->IsMemNoDisplacementOp()) {
		if (Opnd->HasSIBByte()) { // has SIB info
			StringPrintSIB(Opnd, false, OutString, Has64BitAddressing);
		}
		else { // no SIB info
			STARS_regnum_t BaseReg = Opnd->GetReg();
			(void) SMP_strncat(OutString, " [", STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, MDGetRegNumName(BaseReg, ByteWidth), STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, "] ", STARS_MAXSTR - 1);
		}
		if (Opnd->GetAddr() != 0) {
			SMP_msg(" \n ERROR: addr for o_phrase type: %llx\n", (unsigned long long) Opnd->GetAddr());
		}
	}
	else if (Opnd->IsMemDisplacementOp()) {
		STARS_ea_t offset = Opnd->GetAddr();
		int SignedOffset = (int) offset;
		if (Opnd->HasSIBByte()) {
			StringPrintSIB(Opnd, (SignedOffset != 0), OutString, Has64BitAddressing);
			if (SignedOffset > 0) { // print plus sign
				(void) SMP_strncat(OutString, "+", STARS_MAXSTR - 1);
			}
			(void) SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t) Opnd->GetImmedValue());
#else
			(void)SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t)SignedOffset);
			SMP_msg("INFO: StringPrintOperand case reached: MemDisplacement with SIB byte.\n");
#endif
			(void) SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, "]", STARS_MAXSTR - 1);
		}
		else {
			STARS_regnum_t BaseReg = Opnd->GetReg();
			(void) SMP_strncat(OutString, " [", STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, MDGetRegNumName(BaseReg, ByteWidth), STARS_MAXSTR - 1);
			if (SignedOffset >= 0) { // print plus sign
				(void) SMP_strncat(OutString, "+", STARS_MAXSTR - 1);
			}
			(void) SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t)SignedOffset);
			(void) SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1);
			(void) SMP_strncat(OutString, "] ", STARS_MAXSTR - 1);
		}
	}
	else if (Opnd->IsRegOp()) {
		SMP_strncat(OutString, MDGetRegName(Opnd), STARS_MAXSTR - 1);
	}
	else if (Opnd->IsImmedOp()) {
		SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, "%lld", (int64_t) Opnd->GetImmedValue());
		SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1);
	}
	else if ((Opnd->IsFarPointer()) || (Opnd->IsNearPointer())) {
		SMP_snprintf(DummyBuf, STARS_MAXSTR - 1, " %llx", (uint64_t) Opnd->GetAddr());
		SMP_strncat(OutString, DummyBuf, STARS_MAXSTR - 1);
	}
	else {
		SMP_strncat(OutString, " ERROROP", STARS_MAXSTR - 1);
	}
	OutStream += OutString;
	return;
} // end of StringPrintOperand()

void PrintOpcode(uint16_t opcode, FILE *OutFile) {
		case STARS_NN_null:                // Unknown Operation
		case STARS_NN_aaa:                 // ASCII Adjust after Addition
		case STARS_NN_aad:                 // ASCII Adjust AX before Division
		case STARS_NN_aam:                 // ASCII Adjust AX after Multiply
		case STARS_NN_aas:                 // ASCII Adjust AL after Subtraction
		case STARS_NN_adc:                 // Add with Carry
		case STARS_NN_arpl:                // Adjust RPL Field of Selector
		case STARS_NN_bound:               // Check Array Index Against Bounds
		case STARS_NN_bsf:                 // Bit Scan Forward
		case STARS_NN_bsr:                 // Bit Scan Reverse
		case STARS_NN_bt:                  // Bit Test
		case STARS_NN_btc:                 // Bit Test and Complement
		case STARS_NN_btr:                 // Bit Test and Reset
		case STARS_NN_bts:                 // Bit Test and Set
		case STARS_NN_call:                // Call Procedure
		case STARS_NN_callfi:              // Indirect Call Far Procedure
		case STARS_NN_callni:              // Indirect Call Near Procedure
		case STARS_NN_cbw:                 // AL -> AX (with sign)
		case STARS_NN_cwde:                // AX -> EAX (with sign)
		case STARS_NN_cdqe:                // EAX -> RAX (with sign)
		case STARS_NN_clc:                 // Clear Carry Flag
		case STARS_NN_cld:                 // Clear Direction Flag
		case STARS_NN_cli:                 // Clear Interrupt Flag
		case STARS_NN_clts:                // Clear Task-Switched Flag in CR0
		case STARS_NN_cmc:                 // Complement Carry Flag
		case STARS_NN_cmp:                 // Compare Two Operands
		case STARS_NN_cmps:                // Compare Strings
		case STARS_NN_cwd:                 // AX -> DX:AX (with sign)
		case STARS_NN_cdq:                 // EAX -> EDX:EAX (with sign)
		case STARS_NN_cqo:                 // RAX -> RDX:RAX (with sign)
		case STARS_NN_daa:                 // Decimal Adjust AL after Addition
		case STARS_NN_das:                 // Decimal Adjust AL after Subtraction
		case STARS_NN_dec:                 // Decrement by 1
		case STARS_NN_div:                 // Unsigned Divide
		case STARS_NN_enterw:              // Make Stack Frame for Procedure Parameters
		case STARS_NN_enter:               // Make Stack Frame for Procedure Parameters
		case STARS_NN_enterd:              // Make Stack Frame for Procedure Parameters
		case STARS_NN_enterq:              // Make Stack Frame for Procedure Parameters
		case STARS_NN_idiv:                // Signed Divide
		case STARS_NN_imul:                // Signed Multiply
		case STARS_NN_in:                  // Input from Port
		case STARS_NN_inc:                 // Increment by 1
		case STARS_NN_ins:                 // Input Byte(s) from Port to String
		case STARS_NN_int:                 // Call to Interrupt Procedure
		case STARS_NN_into:                // Call to Interrupt Procedure if Overflow Flag = 1
		case STARS_NN_int3:                // Trap to Debugger
		case STARS_NN_iretw:               // Interrupt Return
		case STARS_NN_iret:                // Interrupt Return
		case STARS_NN_iretd:               // Interrupt Return (use32)
		case STARS_NN_iretq:               // Interrupt Return (use64)
		case STARS_NN_ja:                  // Jump if Above (CF=0 & ZF=0)
		case STARS_NN_jae:                 // Jump if Above or Equal (CF=0)
		case STARS_NN_jb:                  // Jump if Below (CF=1)
		case STARS_NN_jbe:                 // Jump if Below or Equal (CF=1 | ZF=1)
		case STARS_NN_jc:                  // Jump if Carry (CF=1)
		case STARS_NN_jcxz:                // Jump if CX is 0
		case STARS_NN_jecxz:               // Jump if ECX is 0
		case STARS_NN_jrcxz:               // Jump if RCX is 0
		case STARS_NN_je:                  // Jump if Equal (ZF=1)
		case STARS_NN_jg:                  // Jump if Greater (ZF=0 & SF=OF)
		case STARS_NN_jge:                 // Jump if Greater or Equal (SF=OF)
		case STARS_NN_jl:                  // Jump if Less (SF!=OF)
		case STARS_NN_jle:                 // Jump if Less or Equal (ZF=1 | SF!=OF)
		case STARS_NN_jna:                 // Jump if Not Above (CF=1 | ZF=1)
		case STARS_NN_jnae:                // Jump if Not Above or Equal (CF=1)
		case STARS_NN_jnb:                 // Jump if Not Below (CF=0)
		case STARS_NN_jnbe:                // Jump if Not Below or Equal (CF=0 & ZF=0)
		case STARS_NN_jnc:                 // Jump if Not Carry (CF=0)
		case STARS_NN_jne:                 // Jump if Not Equal (ZF=0)
		case STARS_NN_jng:                 // Jump if Not Greater (ZF=1 | SF!=OF)
		case STARS_NN_jnge:                // Jump if Not Greater or Equal (ZF=1)
		case STARS_NN_jnl:                 // Jump if Not Less (SF=OF)
		case STARS_NN_jnle:                // Jump if Not Less or Equal (ZF=0 & SF=OF)
		case STARS_NN_jno:                 // Jump if Not Overflow (OF=0)
		case STARS_NN_jnp:                 // Jump if Not Parity (PF=0)
		case STARS_NN_jns:                 // Jump if Not Sign (SF=0)
		case STARS_NN_jnz:                 // Jump if Not Zero (ZF=0)
		case STARS_NN_jo:                  // Jump if Overflow (OF=1)
		case STARS_NN_jp:                  // Jump if Parity (PF=1)
		case STARS_NN_jpe:                 // Jump if Parity Even (PF=1)
		case STARS_NN_jpo:                 // Jump if Parity Odd  (PF=0)
		case STARS_NN_js:                  // Jump if Sign (SF=1)
		case STARS_NN_jz:                  // Jump if Zero (ZF=1)
		case STARS_NN_jmp:                 // Jump
		case STARS_NN_jmpfi:               // Indirect Far Jump
		case STARS_NN_jmpni:               // Indirect Near Jump
		case STARS_NN_jmpshort:            // Jump Short (not used)
		case STARS_NN_lahf:                // Load Flags into AH Register
		case STARS_NN_lar:                 // Load Access Right Byte
		case STARS_NN_lea:                 // Load Effective Address
		case STARS_NN_leavew:              // High Level Procedure Exit
		case STARS_NN_leave:               // High Level Procedure Exit
		case STARS_NN_leaved:              // High Level Procedure Exit
		case STARS_NN_leaveq:              // High Level Procedure Exit
		case STARS_NN_lgdt:                // Load Global Descriptor Table Register
		case STARS_NN_lidt:                // Load Interrupt Descriptor Table Register
		case STARS_NN_lgs:                 // Load Full Pointer to GS:xx
		case STARS_NN_lss:                 // Load Full Pointer to SS:xx
		case STARS_NN_lds:                 // Load Full Pointer to DS:xx
		case STARS_NN_les:                 // Load Full Pointer to ES:xx
		case STARS_NN_lfs:                 // Load Full Pointer to FS:xx
		case STARS_NN_lldt:                // Load Local Descriptor Table Register
		case STARS_NN_lmsw:                // Load Machine Status Word
		case STARS_NN_lock:                // Assert LOCK# Signal Prefix
		case STARS_NN_loopw:               // Loop while ECX != 0
		case STARS_NN_loop:                // Loop while CX != 0
		case STARS_NN_loopd:               // Loop while ECX != 0
		case STARS_NN_loopq:               // Loop while RCX != 0
		case STARS_NN_loopwe:              // Loop while CX != 0 and ZF=1
		case STARS_NN_loope:               // Loop while rCX != 0 and ZF=1
		case STARS_NN_loopde:              // Loop while ECX != 0 and ZF=1
		case STARS_NN_loopqe:              // Loop while RCX != 0 and ZF=1
		case STARS_NN_loopwne:             // Loop while CX != 0 and ZF=0
		case STARS_NN_loopne:              // Loop while rCX != 0 and ZF=0
		case STARS_NN_loopdne:             // Loop while ECX != 0 and ZF=0
		case STARS_NN_loopqne:             // Loop while RCX != 0 and ZF=0
		case STARS_NN_lsl:                 // Load Segment Limit
		case STARS_NN_ltr:                 // Load Task Register
		case STARS_NN_movsp:               // Move to/from Special Registers
		case STARS_NN_movs:                // Move Byte(s) from String to String
		case STARS_NN_movsx:               // Move with Sign-Extend
		case STARS_NN_movzx:               // Move with Zero-Extend
		case STARS_NN_mul:                 // Unsigned Multiplication of AL or AX
		case STARS_NN_neg:                 // Two's Complement Negation
		case STARS_NN_not:                 // One's Complement Negation
		case STARS_NN_or:                  // Logical Inclusive OR
		case STARS_NN_out:                 // Output to Port
		case STARS_NN_outs:                // Output Byte(s) to Port
		case STARS_NN_pop:                 // Pop a word from the Stack
		case STARS_NN_popaw:               // Pop all General Registers
		case STARS_NN_popa:                // Pop all General Registers
		case STARS_NN_popad:               // Pop all General Registers (use32)
		case STARS_NN_popaq:               // Pop all General Registers (use64)
		case STARS_NN_popfw:               // Pop Stack into Flags Register
		case STARS_NN_popf:                // Pop Stack into Flags Register
		case STARS_NN_popfd:               // Pop Stack into Eflags Register
		case STARS_NN_popfq:               // Pop Stack into Rflags Register
		case STARS_NN_push:                // Push Operand onto the Stack
		case STARS_NN_pushaw:              // Push all General Registers
		case STARS_NN_pusha:               // Push all General Registers
		case STARS_NN_pushad:              // Push all General Registers (use32)
		case STARS_NN_pushaq:              // Push all General Registers (use64)
		case STARS_NN_pushfw:              // Push Flags Register onto the Stack
		case STARS_NN_pushf:               // Push Flags Register onto the Stack
		case STARS_NN_pushfd:              // Push Flags Register onto the Stack (use32)
		case STARS_NN_pushfq:              // Push Flags Register onto the Stack (use64)
		case STARS_NN_rcl:                 // Rotate Through Carry Left
		case STARS_NN_rcr:                 // Rotate Through Carry Right
		case STARS_NN_rol:                 // Rotate Left
		case STARS_NN_ror:                 // Rotate Right
		case STARS_NN_rep:                 // Repeat String Operation
		case STARS_NN_repe:                // Repeat String Operation while ZF=1
		case STARS_NN_repne:               // Repeat String Operation while ZF=0
		case STARS_NN_retn:                // Return Near from Procedure
		case STARS_NN_retf:                // Return Far from Procedure
			SMP_fprintf(OutFile, "return");
			break;
		case STARS_NN_sahf:                // Store AH into Flags Register
		case STARS_NN_sal:                 // Shift Arithmetic Left
		case STARS_NN_sar:                 // Shift Arithmetic Right
		case STARS_NN_shl:                 // Shift Logical Left
		case STARS_NN_shr:                 // Shift Logical Right
		case STARS_NN_sbb:                 // Integer Subtraction with Borrow
		case STARS_NN_scas:                // Compare String
		case STARS_NN_seta:                // Set Byte if Above (CF=0 & ZF=0)
		case STARS_NN_setae:               // Set Byte if Above or Equal (CF=0)
		case STARS_NN_setb:                // Set Byte if Below (CF=1)
		case STARS_NN_setbe:               // Set Byte if Below or Equal (CF=1 | ZF=1)
		case STARS_NN_setc:                // Set Byte if Carry (CF=1)
		case STARS_NN_sete:                // Set Byte if Equal (ZF=1)
		case STARS_NN_setg:                // Set Byte if Greater (ZF=0 & SF=OF)
		case STARS_NN_setge:               // Set Byte if Greater or Equal (SF=OF)
		case STARS_NN_setl:                // Set Byte if Less (SF!=OF)
		case STARS_NN_setle:               // Set Byte if Less or Equal (ZF=1 | SF!=OF)
		case STARS_NN_setna:               // Set Byte if Not Above (CF=1 | ZF=1)
		case STARS_NN_setnae:              // Set Byte if Not Above or Equal (CF=1)
		case STARS_NN_setnb:               // Set Byte if Not Below (CF=0)
		case STARS_NN_setnbe:              // Set Byte if Not Below or Equal (CF=0 & ZF=0)
		case STARS_NN_setnc:               // Set Byte if Not Carry (CF=0)
		case STARS_NN_setne:               // Set Byte if Not Equal (ZF=0)
		case STARS_NN_setng:               // Set Byte if Not Greater (ZF=1 | SF!=OF)
		case STARS_NN_setnge:              // Set Byte if Not Greater or Equal (ZF=1)
		case STARS_NN_setnl:               // Set Byte if Not Less (SF=OF)
		case STARS_NN_setnle:              // Set Byte if Not Less or Equal (ZF=0 & SF=OF)
		case STARS_NN_setno:               // Set Byte if Not Overflow (OF=0)
		case STARS_NN_setnp:               // Set Byte if Not Parity (PF=0)
		case STARS_NN_setns:               // Set Byte if Not Sign (SF=0)
		case STARS_NN_setnz:               // Set Byte if Not Zero (ZF=0)
		case STARS_NN_seto:                // Set Byte if Overflow (OF=1)
		case STARS_NN_setp:                // Set Byte if Parity (PF=1)
		case STARS_NN_setpe:               // Set Byte if Parity Even (PF=1)
		case STARS_NN_setpo:               // Set Byte if Parity Odd  (PF=0)
		case STARS_NN_sets:                // Set Byte if Sign (SF=1)
		case STARS_NN_setz:                // Set Byte if Zero (ZF=1)
		case STARS_NN_sgdt:                // Store Global Descriptor Table Register
		case STARS_NN_sidt:                // Store Interrupt Descriptor Table Register
		case STARS_NN_shld:                // Double Precision Shift Left
		case STARS_NN_shrd:                // Double Precision Shift Right
		case STARS_NN_sldt:                // Store Local Descriptor Table Register
		case STARS_NN_smsw:                // Store Machine Status Word
		case STARS_NN_stc:                 // Set Carry Flag
		case STARS_NN_std:                 // Set Direction Flag
		case STARS_NN_sti:                 // Set Interrupt Flag
		case STARS_NN_stos:                // Store String
		case STARS_NN_str:                 // Store Task Register
		case STARS_NN_sub:                 // Integer Subtraction
		case STARS_NN_test:                // Logical Compare
		case STARS_NN_verr:                // Verify a Segment for Reading
		case STARS_NN_verw:                // Verify a Segment for Writing
		case STARS_NN_wait:                // Wait until BUSY# Pin is Inactive (HIGH)
		case STARS_NN_xchg:                // Exchange Register/Memory with Register
		case STARS_NN_xlat:                // Table Lookup Translation
		case STARS_NN_xor:                 // Logical Exclusive OR
		case STARS_NN_cmpxchg:             // Compare and Exchange
		case STARS_NN_bswap:               // Swap bits in EAX
		case STARS_NN_xadd:                // t<-dest; dest<-src+dest; src<-t
		case STARS_NN_invd:                // Invalidate Data Cache
		case STARS_NN_wbinvd:              // Invalidate Data Cache (write changes)
		case STARS_NN_invlpg:              // Invalidate TLB entry
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      Pentium instructions
//

		case STARS_NN_rdmsr:               // Read Machine Status Register
		case STARS_NN_wrmsr:               // Write Machine Status Register
		case STARS_NN_cpuid:               // Get CPU ID
		case STARS_NN_cmpxchg8b:           // Compare and Exchange Eight Bytes
		case STARS_NN_rdtsc:               // Read Time Stamp Counter
		case STARS_NN_rsm:                 // Resume from System Management Mode
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      Pentium Pro instructions
//

		case STARS_NN_cmova:               // Move if Above (CF=0 & ZF=0)
		case STARS_NN_cmovb:               // Move if Below (CF=1)
		case STARS_NN_cmovbe:              // Move if Below or Equal (CF=1 | ZF=1)
		case STARS_NN_cmovg:               // Move if Greater (ZF=0 & SF=OF)
		case STARS_NN_cmovge:              // Move if Greater or Equal (SF=OF)
		case STARS_NN_cmovl:               // Move if Less (SF!=OF)
		case STARS_NN_cmovle:              // Move if Less or Equal (ZF=1 | SF!=OF)
		case STARS_NN_cmovnb:              // Move if Not Below (CF=0)
		case STARS_NN_cmovno:              // Move if Not Overflow (OF=0)
		case STARS_NN_cmovnp:              // Move if Not Parity (PF=0)
		case STARS_NN_cmovns:              // Move if Not Sign (SF=0)
		case STARS_NN_cmovnz:              // Move if Not Zero (ZF=0)
		case STARS_NN_cmovo:               // Move if Overflow (OF=1)
		case STARS_NN_cmovp:               // Move if Parity (PF=1)
		case STARS_NN_cmovs:               // Move if Sign (SF=1)
		case STARS_NN_cmovz:               // Move if Zero (ZF=1)
		case STARS_NN_fcmovb:              // Floating Move if Below
		case STARS_NN_fcmove:              // Floating Move if Equal
		case STARS_NN_fcmovbe:             // Floating Move if Below or Equal
		case STARS_NN_fcmovu:              // Floating Move if Unordered
		case STARS_NN_fcmovnb:             // Floating Move if Not Below
		case STARS_NN_fcmovne:             // Floating Move if Not Equal
		case STARS_NN_fcmovnbe:            // Floating Move if Not Below or Equal
		case STARS_NN_fcmovnu:             // Floating Move if Not Unordered
		case STARS_NN_fcomi:               // FP Compare, result in EFLAGS
		case STARS_NN_fucomi:              // FP Unordered Compare, result in EFLAGS
		case STARS_NN_fcomip:              // FP Compare, result in EFLAGS, pop stack
		case STARS_NN_fucomip:             // FP Unordered Compare, result in EFLAGS, pop stack
		case STARS_NN_rdpmc:               // Read Performance Monitor Counter
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      FPP instructions
//

		case STARS_NN_fld:                 // Load Real
		case STARS_NN_fst:                 // Store Real
		case STARS_NN_fstp:                // Store Real and Pop
		case STARS_NN_fxch:                // Exchange Registers
		case STARS_NN_fild:                // Load Integer
		case STARS_NN_fist:                // Store Integer
		case STARS_NN_fistp:               // Store Integer and Pop
		case STARS_NN_fbld:                // Load BCD
		case STARS_NN_fbstp:               // Store BCD and Pop
		case STARS_NN_fadd:                // Add Real
		case STARS_NN_faddp:               // Add Real and Pop
		case STARS_NN_fiadd:               // Add Integer
		case STARS_NN_fsub:                // Subtract Real
		case STARS_NN_fsubp:               // Subtract Real and Pop
		case STARS_NN_fisub:               // Subtract Integer
		case STARS_NN_fsubr:               // Subtract Real Reversed
		case STARS_NN_fsubrp:              // Subtract Real Reversed and Pop
		case STARS_NN_fisubr:              // Subtract Integer Reversed
		case STARS_NN_fmul:                // Multiply Real
		case STARS_NN_fmulp:               // Multiply Real and Pop
		case STARS_NN_fimul:               // Multiply Integer
		case STARS_NN_fdiv:                // Divide Real
		case STARS_NN_fdivp:               // Divide Real and Pop
		case STARS_NN_fidiv:               // Divide Integer
		case STARS_NN_fdivr:               // Divide Real Reversed
		case STARS_NN_fdivrp:              // Divide Real Reversed and Pop
		case STARS_NN_fidivr:              // Divide Integer Reversed
		case STARS_NN_fsqrt:               // Square Root
		case STARS_NN_fscale:              // Scale:  st(0) <- st(0) * 2^st(1)
		case STARS_NN_fprem:               // Partial Remainder
		case STARS_NN_frndint:             // Round to Integer
		case STARS_NN_fxtract:             // Extract exponent and significand
		case STARS_NN_fabs:                // Absolute value
		case STARS_NN_fchs:                // Change Sign
		case STARS_NN_fcom:                // Compare Real
		case STARS_NN_fcomp:               // Compare Real and Pop
		case STARS_NN_fcompp:              // Compare Real and Pop Twice
		case STARS_NN_ficom:               // Compare Integer
		case STARS_NN_ficomp:              // Compare Integer and Pop
		case STARS_NN_ftst:                // Test
		case STARS_NN_fxam:                // Examine
		case STARS_NN_fptan:               // Partial tangent
		case STARS_NN_fpatan:              // Partial arctangent
		case STARS_NN_f2xm1:               // 2^x - 1
		case STARS_NN_fyl2x:               // Y * lg2(X)
		case STARS_NN_fyl2xp1:             // Y * lg2(X+1)
		case STARS_NN_fldz:                // Load +0.0
		case STARS_NN_fld1:                // Load +1.0
		case STARS_NN_fldpi:               // Load PI=3.14...
		case STARS_NN_fldl2t:              // Load lg2(10)
		case STARS_NN_fldl2e:              // Load lg2(e)
		case STARS_NN_fldlg2:              // Load lg10(2)
		case STARS_NN_fldln2:              // Load ln(2)
		case STARS_NN_finit:               // Initialize Processor
		case STARS_NN_fninit:              // Initialize Processor (no wait)
		case STARS_NN_fsetpm:              // Set Protected Mode
		case STARS_NN_fldcw:               // Load Control Word
		case STARS_NN_fstcw:               // Store Control Word
		case STARS_NN_fnstcw:              // Store Control Word (no wait)
		case STARS_NN_fstsw:               // Store Status Word
		case STARS_NN_fnstsw:              // Store Status Word (no wait)
		case STARS_NN_fclex:               // Clear Exceptions
		case STARS_NN_fnclex:              // Clear Exceptions (no wait)
		case STARS_NN_fstenv:              // Store Environment
		case STARS_NN_fnstenv:             // Store Environment (no wait)
		case STARS_NN_fldenv:              // Load Environment
		case STARS_NN_fsave:               // Save State
		case STARS_NN_fnsave:              // Save State (no wait)
		case STARS_NN_frstor:              // Restore State
		case STARS_NN_fincstp:             // Increment Stack Pointer
		case STARS_NN_fdecstp:             // Decrement Stack Pointer
		case STARS_NN_ffree:               // Free Register
		case STARS_NN_fnop:                // No Operation
		case STARS_NN_feni:                // (8087 only)
		case STARS_NN_fneni:               // (no wait) (8087 only)
		case STARS_NN_fdisi:               // (8087 only)
		case STARS_NN_fndisi:              // (no wait) (8087 only)
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      80387 instructions
//

		case STARS_NN_fprem1:              // Partial Remainder ( < half )
		case STARS_NN_fsincos:             // t<-cos(st); st<-sin(st); push t
		case STARS_NN_fsin:                // Sine
		case STARS_NN_fcos:                // Cosine
		case STARS_NN_fucom:               // Compare Unordered Real
		case STARS_NN_fucomp:              // Compare Unordered Real and Pop
		case STARS_NN_fucompp:             // Compare Unordered Real and Pop Twice
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      Instructions added 28.02.96
//

		case STARS_NN_setalc:              // Set AL to Carry Flag
		case STARS_NN_svdc:                // Save Register and Descriptor
		case STARS_NN_rsdc:                // Restore Register and Descriptor
		case STARS_NN_svldt:               // Save LDTR and Descriptor
		case STARS_NN_rsldt:               // Restore LDTR and Descriptor
		case STARS_NN_svts:                // Save TR and Descriptor
		case STARS_NN_rsts:                // Restore TR and Descriptor
		case STARS_NN_icebp:               // ICE Break Point
		case STARS_NN_loadall:             // Load the entire CPU state from ES:EDI
			SMP_fprintf(OutFile, "ERROR");
			break;

//
//      MMX instructions
//

		case STARS_NN_emms:                // Empty MMX state
		case STARS_NN_movd:                // Move 32 bits
		case STARS_NN_movq:                // Move 64 bits
		case STARS_NN_packsswb:            // Pack with Signed Saturation (Word->Byte)
		case STARS_NN_packssdw:            // Pack with Signed Saturation (Dword->Word)
		case STARS_NN_packuswb:            // Pack with Unsigned Saturation (Word->Byte)
		case STARS_NN_paddb:               // Packed Add Byte
		case STARS_NN_paddw:               // Packed Add Word
		case STARS_NN_paddd:               // Packed Add Dword
		case STARS_NN_paddsb:              // Packed Add with Saturation (Byte)
		case STARS_NN_paddsw:              // Packed Add with Saturation (Word)
		case STARS_NN_paddusb:             // Packed Add Unsigned with Saturation (Byte)
		case STARS_NN_paddusw:             // Packed Add Unsigned with Saturation (Word)
		case STARS_NN_pand:                // Bitwise Logical And
		case STARS_NN_pandn:               // Bitwise Logical And Not
		case STARS_NN_pcmpeqb:             // Packed Compare for Equal (Byte)
		case STARS_NN_pcmpeqw:             // Packed Compare for Equal (Word)
		case STARS_NN_pcmpeqd:             // Packed Compare for Equal (Dword)
		case STARS_NN_pcmpgtb:             // Packed Compare for Greater Than (Byte)
		case STARS_NN_pcmpgtw:             // Packed Compare for Greater Than (Word)
		case STARS_NN_pcmpgtd:             // Packed Compare for Greater Than (Dword)
		case STARS_NN_pmaddwd:             // Packed Multiply and Add
		case STARS_NN_pmulhw:              // Packed Multiply High
		case STARS_NN_pmullw:              // Packed Multiply Low
		case STARS_NN_por:                 // Bitwise Logical Or
		case STARS_NN_psllw:               // Packed Shift Left Logical (Word)
		case STARS_NN_pslld:               // Packed Shift Left Logical (Dword)
		case STARS_NN_psllq:               // Packed Shift Left Logical (Qword)
		case STARS_NN_psraw:               // Packed Shift Right Arithmetic (Word)
		case STARS_NN_psrad:               // Packed Shift Right Arithmetic (Dword)
		case STARS_NN_psrlw:               // Packed Shift Right Logical (Word)
		case STARS_NN_psrld:               // Packed Shift Right Logical (Dword)