Newer
Older
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
case NN_pushaq: // Push all General Registers (use64)
case NN_pushfw: // Push Flags Register onto the Stack
case NN_pushf: // Push Flags Register onto the Stack
case NN_pushfd: // Push Flags Register onto the Stack (use32)
case NN_pushfq: // Push Flags Register onto the Stack (use64)
return this->BuildPushRTL();
case NN_rcl: // Rotate Through Carry Left
return this->BuildBinaryPlusFlagsRTL(SMP_ROTATE_LEFT_CARRY);
case NN_rcr: // Rotate Through Carry Right
return this->BuildBinaryPlusFlagsRTL(SMP_ROTATE_RIGHT_CARRY);
case NN_rol: // Rotate Left
return this->BuildBinaryRTL(SMP_ROTATE_LEFT);
case NN_ror: // Rotate Right
return this->BuildBinaryRTL(SMP_ROTATE_RIGHT);
case NN_rep: // Repeat String Operation
case NN_repe: // Repeat String Operation while ZF=1
case NN_repne: // Repeat String Operation while ZF=0
return false;
break;
case NN_retn: // Return Near from Procedure
case NN_retf: // Return Far from Procedure
return this->BuildReturnRTL();
case NN_sahf: // Store AH into Flags Register
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
case NN_sal: // Shift Arithmetic Left
return this->BuildBinaryRTL(SMP_S_LEFT_SHIFT);
case NN_sar: // Shift Arithmetic Right
return this->BuildBinaryRTL(SMP_S_RIGHT_SHIFT);
case NN_shl: // Shift Logical Left
return this->BuildBinaryRTL(SMP_U_LEFT_SHIFT);
case NN_shr: // Shift Logical Right
return this->BuildBinaryRTL(SMP_U_RIGHT_SHIFT);
case NN_sbb: // Integer Subtraction with Borrow
return this->BuildBinaryPlusFlagsRTL(SMP_SUBTRACT_BORROW);
case NN_scas: // Compare String
return this->BuildBinaryPlusFlagsRTL(SMP_U_COMPARE);
case NN_seta: // Set Byte if Above (CF=0 & ZF=0)
case NN_setae: // Set Byte if Above or Equal (CF=0)
case NN_setb: // Set Byte if Below (CF=1)
case NN_setbe: // Set Byte if Below or Equal (CF=1 | ZF=1)
case NN_setc: // Set Byte if Carry (CF=1)
case NN_sete: // Set Byte if Equal (ZF=1)
case NN_setg: // Set Byte if Greater (ZF=0 & SF=OF)
case NN_setge: // Set Byte if Greater or Equal (SF=OF)
case NN_setl: // Set Byte if Less (SF!=OF)
case NN_setle: // Set Byte if Less or Equal (ZF=1 | SF!=OF)
case NN_setna: // Set Byte if Not Above (CF=1 | ZF=1)
case NN_setnae: // Set Byte if Not Above or Equal (CF=1)
case NN_setnb: // Set Byte if Not Below (CF=0)
case NN_setnbe: // Set Byte if Not Below or Equal (CF=0 & ZF=0)
case NN_setnc: // Set Byte if Not Carry (CF=0)
case NN_setne: // Set Byte if Not Equal (ZF=0)
case NN_setng: // Set Byte if Not Greater (ZF=1 | SF!=OF)
case NN_setnge: // Set Byte if Not Greater or Equal (ZF=1)
case NN_setnl: // Set Byte if Not Less (SF=OF)
case NN_setnle: // Set Byte if Not Less or Equal (ZF=0 & SF=OF)
case NN_setno: // Set Byte if Not Overflow (OF=0)
case NN_setnp: // Set Byte if Not Parity (PF=0)
case NN_setns: // Set Byte if Not Sign (SF=0)
case NN_setnz: // Set Byte if Not Zero (ZF=0)
case NN_seto: // Set Byte if Overflow (OF=1)
case NN_setp: // Set Byte if Parity (PF=1)
case NN_setpe: // Set Byte if Parity Even (PF=1)
case NN_setpo: // Set Byte if Parity Odd (PF=0)
case NN_sets: // Set Byte if Sign (SF=1)
case NN_setz: // Set Byte if Zero (ZF=1)
// Destination always get set to NUMERIC 0 or 1, depending on
// the condition and the relevant flags bits. Best way to model
// this in an RTL is to perform an unspecified unary NUMERIC
// operation on the flags register and assign the result to the
// destination operand, making it always NUMERIC.
return this->BuildUnary2OpndRTL(SMP_UNARY_NUMERIC_OPERATION);
case NN_sgdt: // Store Global Descriptor Table Register
case NN_sidt: // Store Interrupt Descriptor Table Register
return false;
break;
case NN_shld: // Double Precision Shift Left
return this->BuildDoubleShiftRTL(SMP_U_LEFT_SHIFT);
case NN_shrd: // Double Precision Shift Right
return this->BuildDoubleShiftRTL(SMP_U_RIGHT_SHIFT);
case NN_sldt: // Store Local Descriptor Table Register
case NN_smsw: // Store Machine Status Word
return false;
break;
case NN_stc: // Set Carry Flag
case NN_std: // Set Direction Flag
return this->BuildUnaryRTL(SMP_UNARY_NUMERIC_OPERATION);
case NN_sti: // Set Interrupt Flag
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_stos: // Store String
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
case NN_str: // Store Task Register
return false;
break;
case NN_sub: // Integer Subtraction
return this->BuildBinaryRTL(SMP_SUBTRACT);
case NN_test: // Logical Compare
return this->BuildFlagsDestBinaryRTL(SMP_U_COMPARE);
case NN_verr: // Verify a Segment for Reading
case NN_verw: // Verify a Segment for Writing
case NN_wait: // Wait until BUSY# Pin is Inactive (HIGH)
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
if (NN_wait != this->SMPcmd.itype)
this->RTL.ExtraKills.push_back(FlagsOp);
return true;
case NN_xchg: // Exchange Register/Memory with Register
return this->BuildExchangeRTL();
case NN_xlat: // Table Lookup Translation
return false;
break;
case NN_xor: // Logical Exclusive OR
return this->BuildBinaryRTL(SMP_BITWISE_XOR);
//
// 486 instructions
//
case NN_cmpxchg: // Compare and Exchange
return this->BuildCompareExchangeRTL();
case NN_bswap: // Swap bits in EAX
return this->BuildUnaryRTL(SMP_UNARY_NUMERIC_OPERATION);
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
case NN_xadd: // t<-dest; dest<-src+dest; src<-t
return this->BuildExchangeAddRTL();
case NN_invd: // Invalidate Data Cache
case NN_wbinvd: // Invalidate Data Cache (write changes)
case NN_invlpg: // Invalidate TLB entry
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
//
// Pentium instructions
//
case NN_rdmsr: // Read Machine Status Register
return this->BuildOptType8RTL();
case NN_wrmsr: // Write Machine Status Register
return false;
break;
case NN_cpuid: // Get CPU ID
return this->BuildOptType8RTL();
case NN_cmpxchg8b: // Compare and Exchange Eight Bytes
return false;
break;
case NN_rdtsc: // Read Time Stamp Counter
return this->BuildOptType8RTL();
case NN_rsm: // Resume from System Management Mode
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
//
// Pentium Pro instructions
//
case NN_cmova: // Move if Above (CF=0 & ZF=0)
case NN_cmovb: // Move if Below (CF=1)
case NN_cmovbe: // Move if Below or Equal (CF=1 | ZF=1)
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_cmovg: // Move if Greater (ZF=0 & SF=OF)
return this->BuildMoveRTL(SMP_GREATER_THAN);
case NN_cmovge: // Move if Greater or Equal (SF=OF)
return this->BuildMoveRTL(SMP_GREATER_EQUAL);
case NN_cmovl: // Move if Less (SF!=OF)
return this->BuildMoveRTL(SMP_LESS_THAN);
case NN_cmovle: // Move if Less or Equal (ZF=1 | SF!=OF)
return this->BuildMoveRTL(SMP_LESS_EQUAL);
case NN_cmovnb: // Move if Not Below (CF=0)
case NN_cmovno: // Move if Not Overflow (OF=0)
case NN_cmovnp: // Move if Not Parity (PF=0)
case NN_cmovns: // Move if Not Sign (SF=0)
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_cmovnz: // Move if Not Zero (ZF=0)
return this->BuildMoveRTL(SMP_NOT_EQUAL);
case NN_cmovo: // Move if Overflow (OF=1)
case NN_cmovp: // Move if Parity (PF=1)
case NN_cmovs: // Move if Sign (SF=1)
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_cmovz: // Move if Zero (ZF=1)
return this->BuildMoveRTL(SMP_EQUAL);
case NN_fcmovb: // Floating Move if Below
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcmove: // Floating Move if Equal
return this->BuildMoveRTL(SMP_EQUAL);
case NN_fcmovbe: // Floating Move if Below or Equal
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcmovu: // Floating Move if Unordered
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcmovnb: // Floating Move if Not Below
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcmovne: // Floating Move if Not Equal
return this->BuildMoveRTL(SMP_NOT_EQUAL);
case NN_fcmovnbe: // Floating Move if Not Below or Equal
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcmovnu: // Floating Move if Not Unordered
return this->BuildMoveRTL(SMP_BINARY_NUMERIC_OPERATION);
case NN_fcomi: // FP Compare: result in EFLAGS
case NN_fucomi: // FP Unordered Compare: result in EFLAGS
case NN_fcomip: // FP Compare: result in EFLAGS: pop stack
case NN_fucomip: // FP Unordered Compare: result in EFLAGS: pop stack
return false;
break;
case NN_rdpmc: // Read Performance Monitor Counter
return this->BuildOptType8RTL();
//
// FPP instructions
//
case NN_fld: // Load Real
case NN_fst: // Store Real
case NN_fstp: // Store Real and Pop
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
case NN_fxch: // Exchange Registers
// FP registers remain NUMERIC anyway, so this is a no-op to our type system.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_fild: // Load Integer
case NN_fist: // Store Integer
case NN_fistp: // Store Integer and Pop
case NN_fbld: // Load BCD
case NN_fbstp: // Store BCD and Pop
return this->BuildMoveRTL(SMP_NULL_OPERATOR);
case NN_fadd: // Add Real
case NN_faddp: // Add Real and Pop
case NN_fiadd: // Add Integer
case NN_fsub: // Subtract Real
case NN_fsubp: // Subtract Real and Pop
case NN_fisub: // Subtract Integer
case NN_fsubr: // Subtract Real Reversed
case NN_fsubrp: // Subtract Real Reversed and Pop
case NN_fisubr: // Subtract Integer Reversed
case NN_fmul: // Multiply Real
case NN_fmulp: // Multiply Real and Pop
case NN_fimul: // Multiply Integer
case NN_fdiv: // Divide Real
case NN_fdivp: // Divide Real and Pop
case NN_fidiv: // Divide Integer
case NN_fdivr: // Divide Real Reversed
case NN_fdivrp: // Divide Real Reversed and Pop
case NN_fidivr: // Divide Integer Reversed
return this->BuildBinaryRTL(SMP_BINARY_FLOATING_ARITHMETIC);
case NN_fsqrt: // Square Root
case NN_fscale: // Scale: st(0) <- st(0) * 2^st(1)
case NN_fprem: // Partial Remainder
case NN_frndint: // Round to Integer
case NN_fxtract: // Extract exponent and significand
case NN_fabs: // Absolute value
case NN_fchs: // Change Sign
return this->BuildUnaryRTL(SMP_UNARY_FLOATING_ARITHMETIC);
case NN_fcom: // Compare Real
case NN_fcomp: // Compare Real and Pop
case NN_fcompp: // Compare Real and Pop Twice
case NN_ficom: // Compare Integer
case NN_ficomp: // Compare Integer and Pop
case NN_ftst: // Test
case NN_fxam: // Examine
// Floating comparison instructions use FP reg stack locations
// as sources and set only the FP flags. All of these are numeric
// type and we don't track any of them, so all such instructions
// can be considered to be no-ops.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_fptan: // Partial tangent
case NN_fpatan: // Partial arctangent
case NN_f2xm1: // 2^x - 1
case NN_fyl2x: // Y * lg2(X)
case NN_fyl2xp1: // Y * lg2(X+1)
// We can consider it a unary operation when both arguments come
// off the floating point register stack, unless we ever start
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
// modeling the different locations in the FP register stack.
return this->BuildUnaryRTL(SMP_UNARY_FLOATING_ARITHMETIC);
case NN_fldz: // Load +0.0
case NN_fld1: // Load +1.0
case NN_fldpi: // Load PI=3.14...
case NN_fldl2t: // Load lg2(10)
case NN_fldl2e: // Load lg2(e)
case NN_fldlg2: // Load lg10(2)
case NN_fldln2: // Load ln(2)
case NN_finit: // Initialize Processor
case NN_fninit: // Initialize Processor (no wait)
case NN_fsetpm: // Set Protected Mode
case NN_fldcw: // Load Control Word
case NN_fstcw: // Store Control Word
case NN_fnstcw: // Store Control Word (no wait)
case NN_fstsw: // Store Status Word
case NN_fnstsw: // Store Status Word (no wait)
case NN_fclex: // Clear Exceptions
case NN_fnclex: // Clear Exceptions (no wait)
// Floating point stack and control word and flags operations
// with no memory operands are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
case NN_fstenv: // Store Environment
case NN_fnstenv: // Store Environment (no wait)
case NN_fldenv: // Load Environment
case NN_fsave: // Save State
case NN_fnsave: // Save State (no wait)
case NN_frstor: // Restore State
case NN_fincstp: // Increment Stack Pointer
case NN_fdecstp: // Decrement Stack Pointer
case NN_ffree: // Free Register
return false;
break;
case NN_fnop: // No Operation
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
case NN_feni: // (8087 only)
case NN_fneni: // (no wait) (8087 only)
case NN_fdisi: // (8087 only)
case NN_fndisi: // (no wait) (8087 only)
return false;
break;
//
// 80387 instructions
//
case NN_fprem1: // Partial Remainder ( < half )
case NN_fsincos: // t<-cos(st); st<-sin(st); push t
case NN_fsin: // Sine
case NN_fcos: // Cosine
case NN_fucom: // Compare Unordered Real
case NN_fucomp: // Compare Unordered Real and Pop
case NN_fucompp: // Compare Unordered Real and Pop Twice
// Floating point stack and control word and flags operations
// with no memory operands are no-ops to us.
NopRT = new SMPRegTransfer;
NopRT->SetOperator(SMP_NULL_OPERATOR);
this->RTL.push_back(NopRT);
NopRT = NULL;
return true;
//
// Instructions added 28.02.96
//
case NN_setalc: // Set AL to Carry Flag
case NN_svdc: // Save Register and Descriptor
case NN_rsdc: // Restore Register and Descriptor
case NN_svldt: // Save LDTR and Descriptor
case NN_rsldt: // Restore LDTR and Descriptor
case NN_svts: // Save TR and Descriptor
case NN_rsts: // Restore TR and Descriptor
case NN_icebp: // ICE Break Point
case NN_loadall: // Load the entire CPU state from ES:EDI
//
// MMX instructions
//
case NN_emms: // Empty MMX state
case NN_movd: // Move 32 bits
case NN_movq: // Move 64 bits
case NN_packsswb: // Pack with Signed Saturation (Word->Byte)
case NN_packssdw: // Pack with Signed Saturation (Dword->Word)
case NN_packuswb: // Pack with Unsigned Saturation (Word->Byte)
case NN_paddb: // Packed Add Byte
case NN_paddw: // Packed Add Word
case NN_paddd: // Packed Add Dword
case NN_paddsb: // Packed Add with Saturation (Byte)
case NN_paddsw: // Packed Add with Saturation (Word)
case NN_paddusb: // Packed Add Unsigned with Saturation (Byte)
case NN_paddusw: // Packed Add Unsigned with Saturation (Word)
case NN_pand: // Bitwise Logical And
case NN_pandn: // Bitwise Logical And Not
case NN_pcmpeqb: // Packed Compare for Equal (Byte)
case NN_pcmpeqw: // Packed Compare for Equal (Word)
case NN_pcmpeqd: // Packed Compare for Equal (Dword)
case NN_pcmpgtb: // Packed Compare for Greater Than (Byte)
case NN_pcmpgtw: // Packed Compare for Greater Than (Word)
case NN_pcmpgtd: // Packed Compare for Greater Than (Dword)
case NN_pmaddwd: // Packed Multiply and Add
case NN_pmulhw: // Packed Multiply High
case NN_pmullw: // Packed Multiply Low
case NN_por: // Bitwise Logical Or
case NN_psllw: // Packed Shift Left Logical (Word)
case NN_pslld: // Packed Shift Left Logical (Dword)
case NN_psllq: // Packed Shift Left Logical (Qword)
case NN_psraw: // Packed Shift Right Arithmetic (Word)
case NN_psrad: // Packed Shift Right Arithmetic (Dword)
case NN_psrlw: // Packed Shift Right Logical (Word)
case NN_psrld: // Packed Shift Right Logical (Dword)
case NN_psrlq: // Packed Shift Right Logical (Qword)
case NN_psubb: // Packed Subtract Byte
case NN_psubw: // Packed Subtract Word
case NN_psubd: // Packed Subtract Dword
case NN_psubsb: // Packed Subtract with Saturation (Byte)
case NN_psubsw: // Packed Subtract with Saturation (Word)
case NN_psubusb: // Packed Subtract Unsigned with Saturation (Byte)
case NN_psubusw: // Packed Subtract Unsigned with Saturation (Word)
case NN_punpckhbw: // Unpack High Packed Data (Byte->Word)
case NN_punpckhwd: // Unpack High Packed Data (Word->Dword)
case NN_punpckhdq: // Unpack High Packed Data (Dword->Qword)
case NN_punpcklbw: // Unpack Low Packed Data (Byte->Word)
case NN_punpcklwd: // Unpack Low Packed Data (Word->Dword)
case NN_punpckldq: // Unpack Low Packed Data (Dword->Qword)
case NN_pxor: // Bitwise Logical Exclusive Or
//
// Undocumented Deschutes processor instructions
//
case NN_fxsave: // Fast save FP context
case NN_fxrstor: // Fast restore FP context
// Pentium II instructions
case NN_sysenter: // Fast Transition to System Call Entry Point
case NN_sysexit: // Fast Transition from System Call Entry Point
// 3DNow! instructions
case NN_pavgusb: // Packed 8-bit Unsigned Integer Averaging
case NN_pfadd: // Packed Floating-Point Addition
case NN_pfsub: // Packed Floating-Point Subtraction
case NN_pfsubr: // Packed Floating-Point Reverse Subtraction
case NN_pfacc: // Packed Floating-Point Accumulate
case NN_pfcmpge: // Packed Floating-Point Comparison: Greater or Equal
case NN_pfcmpgt: // Packed Floating-Point Comparison: Greater
case NN_pfcmpeq: // Packed Floating-Point Comparison: Equal
case NN_pfmin: // Packed Floating-Point Minimum
case NN_pfmax: // Packed Floating-Point Maximum
case NN_pi2fd: // Packed 32-bit Integer to Floating-Point
case NN_pf2id: // Packed Floating-Point to 32-bit Integer
case NN_pfrcp: // Packed Floating-Point Reciprocal Approximation
case NN_pfrsqrt: // Packed Floating-Point Reciprocal Square Root Approximation
case NN_pfmul: // Packed Floating-Point Multiplication
case NN_pfrcpit1: // Packed Floating-Point Reciprocal First Iteration Step
case NN_pfrsqit1: // Packed Floating-Point Reciprocal Square Root First Iteration Step
case NN_pfrcpit2: // Packed Floating-Point Reciprocal Second Iteration Step
case NN_pmulhrw: // Packed Floating-Point 16-bit Integer Multiply with rounding
case NN_femms: // Faster entry/exit of the MMX or floating-point state
case NN_prefetch: // Prefetch at least a 32-byte line into L1 data cache
case NN_prefetchw: // Prefetch processor cache line into L1 data cache (mark as modified)
// Pentium III instructions
case NN_addps: // Packed Single-FP Add
case NN_addss: // Scalar Single-FP Add
case NN_andnps: // Bitwise Logical And Not for Single-FP
case NN_andps: // Bitwise Logical And for Single-FP
case NN_cmpps: // Packed Single-FP Compare
case NN_cmpss: // Scalar Single-FP Compare
case NN_comiss: // Scalar Ordered Single-FP Compare and Set EFLAGS
case NN_cvtpi2ps: // Packed signed INT32 to Packed Single-FP conversion
case NN_cvtps2pi: // Packed Single-FP to Packed INT32 conversion
case NN_cvtsi2ss: // Scalar signed INT32 to Single-FP conversion
case NN_cvtss2si: // Scalar Single-FP to signed INT32 conversion
case NN_cvttps2pi: // Packed Single-FP to Packed INT32 conversion (truncate)
case NN_cvttss2si: // Scalar Single-FP to signed INT32 conversion (truncate)
case NN_divps: // Packed Single-FP Divide
case NN_divss: // Scalar Single-FP Divide
case NN_ldmxcsr: // Load Streaming SIMD Extensions Technology Control/Status Register
case NN_maxps: // Packed Single-FP Maximum
case NN_maxss: // Scalar Single-FP Maximum
case NN_minps: // Packed Single-FP Minimum
case NN_minss: // Scalar Single-FP Minimum
case NN_movaps: // Move Aligned Four Packed Single-FP
case NN_movhlps: // Move High to Low Packed Single-FP
case NN_movhps: // Move High Packed Single-FP
case NN_movlhps: // Move Low to High Packed Single-FP
case NN_movlps: // Move Low Packed Single-FP
case NN_movmskps: // Move Mask to Register
case NN_movss: // Move Scalar Single-FP
case NN_movups: // Move Unaligned Four Packed Single-FP
case NN_mulps: // Packed Single-FP Multiply
case NN_mulss: // Scalar Single-FP Multiply
case NN_orps: // Bitwise Logical OR for Single-FP Data
case NN_rcpps: // Packed Single-FP Reciprocal
case NN_rcpss: // Scalar Single-FP Reciprocal
case NN_rsqrtps: // Packed Single-FP Square Root Reciprocal
case NN_rsqrtss: // Scalar Single-FP Square Root Reciprocal
case NN_shufps: // Shuffle Single-FP
case NN_sqrtps: // Packed Single-FP Square Root
case NN_sqrtss: // Scalar Single-FP Square Root
case NN_stmxcsr: // Store Streaming SIMD Extensions Technology Control/Status Register
case NN_subps: // Packed Single-FP Subtract
case NN_subss: // Scalar Single-FP Subtract
case NN_ucomiss: // Scalar Unordered Single-FP Compare and Set EFLAGS
case NN_unpckhps: // Unpack High Packed Single-FP Data
case NN_unpcklps: // Unpack Low Packed Single-FP Data
case NN_xorps: // Bitwise Logical XOR for Single-FP Data
case NN_pavgb: // Packed Average (Byte)
case NN_pavgw: // Packed Average (Word)
case NN_pextrw: // Extract Word
case NN_pinsrw: // Insert Word
case NN_pmaxsw: // Packed Signed Integer Word Maximum
case NN_pmaxub: // Packed Unsigned Integer Byte Maximum
case NN_pminsw: // Packed Signed Integer Word Minimum
case NN_pminub: // Packed Unsigned Integer Byte Minimum
case NN_pmovmskb: // Move Byte Mask to Integer
case NN_pmulhuw: // Packed Multiply High Unsigned
case NN_psadbw: // Packed Sum of Absolute Differences
case NN_pshufw: // Packed Shuffle Word
case NN_maskmovq: // Byte Mask write
case NN_movntps: // Move Aligned Four Packed Single-FP Non Temporal
case NN_movntq: // Move 64 Bits Non Temporal
case NN_prefetcht0: // Prefetch to all cache levels
case NN_prefetcht1: // Prefetch to all cache levels
case NN_prefetcht2: // Prefetch to L2 cache
case NN_prefetchnta: // Prefetch to L1 cache
case NN_sfence: // Store Fence
// Pentium III Pseudo instructions
case NN_cmpeqps: // Packed Single-FP Compare EQ
case NN_cmpltps: // Packed Single-FP Compare LT
case NN_cmpleps: // Packed Single-FP Compare LE
case NN_cmpunordps: // Packed Single-FP Compare UNORD
case NN_cmpneqps: // Packed Single-FP Compare NOT EQ
case NN_cmpnltps: // Packed Single-FP Compare NOT LT
case NN_cmpnleps: // Packed Single-FP Compare NOT LE
case NN_cmpordps: // Packed Single-FP Compare ORDERED
case NN_cmpeqss: // Scalar Single-FP Compare EQ
case NN_cmpltss: // Scalar Single-FP Compare LT
case NN_cmpless: // Scalar Single-FP Compare LE
case NN_cmpunordss: // Scalar Single-FP Compare UNORD
case NN_cmpneqss: // Scalar Single-FP Compare NOT EQ
case NN_cmpnltss: // Scalar Single-FP Compare NOT LT
case NN_cmpnless: // Scalar Single-FP Compare NOT LE
case NN_cmpordss: // Scalar Single-FP Compare ORDERED
// AMD K7 instructions
case NN_pf2iw: // Packed Floating-Point to Integer with Sign Extend
case NN_pfnacc: // Packed Floating-Point Negative Accumulate
case NN_pfpnacc: // Packed Floating-Point Mixed Positive-Negative Accumulate
case NN_pi2fw: // Packed 16-bit Integer to Floating-Point
case NN_pswapd: // Packed Swap Double Word
// Undocumented FP instructions (thanks to norbert.juffa@adm.com)
case NN_fstp1: // Alias of Store Real and Pop
case NN_fcom2: // Alias of Compare Real
case NN_fcomp3: // Alias of Compare Real and Pop
case NN_fxch4: // Alias of Exchange Registers
case NN_fcomp5: // Alias of Compare Real and Pop
case NN_ffreep: // Free Register and Pop
case NN_fxch7: // Alias of Exchange Registers
case NN_fstp8: // Alias of Store Real and Pop
case NN_fstp9: // Alias of Store Real and Pop
// Pentium 4 instructions
case NN_addpd: // Add Packed Double-Precision Floating-Point Values
case NN_addsd: // Add Scalar Double-Precision Floating-Point Values
case NN_andnpd: // Bitwise Logical AND NOT of Packed Double-Precision Floating-Point Values
case NN_andpd: // Bitwise Logical AND of Packed Double-Precision Floating-Point Values
case NN_clflush: // Flush Cache Line
case NN_cmppd: // Compare Packed Double-Precision Floating-Point Values
case NN_cmpsd: // Compare Scalar Double-Precision Floating-Point Values
case NN_comisd: // Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
case NN_cvtdq2pd: // Convert Packed Doubleword Integers to Packed Single-Precision Floating-Point Values
case NN_cvtdq2ps: // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
case NN_cvtpd2dq: // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtpd2pi: // Convert Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtpd2ps: // Convert Packed Double-Precision Floating-Point Values to Packed Single-Precision Floating-Point Values
case NN_cvtpi2pd: // Convert Packed Doubleword Integers to Packed Double-Precision Floating-Point Values
case NN_cvtps2dq: // Convert Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvtps2pd: // Convert Packed Single-Precision Floating-Point Values to Packed Double-Precision Floating-Point Values
case NN_cvtsd2si: // Convert Scalar Double-Precision Floating-Point Value to Doubleword Integer
case NN_cvtsd2ss: // Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value
case NN_cvtsi2sd: // Convert Doubleword Integer to Scalar Double-Precision Floating-Point Value
case NN_cvtss2sd: // Convert Scalar Single-Precision Floating-Point Value to Scalar Double-Precision Floating-Point Value
case NN_cvttpd2dq: // Convert With Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttpd2pi: // Convert with Truncation Packed Double-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttps2dq: // Convert With Truncation Packed Single-Precision Floating-Point Values to Packed Doubleword Integers
case NN_cvttsd2si: // Convert with Truncation Scalar Double-Precision Floating-Point Value to Doubleword Integer
case NN_divpd: // Divide Packed Double-Precision Floating-Point Values
case NN_divsd: // Divide Scalar Double-Precision Floating-Point Values
case NN_lfence: // Load Fence
case NN_maskmovdqu: // Store Selected Bytes of Double Quadword
case NN_maxpd: // Return Maximum Packed Double-Precision Floating-Point Values
case NN_maxsd: // Return Maximum Scalar Double-Precision Floating-Point Value
case NN_mfence: // Memory Fence
case NN_minpd: // Return Minimum Packed Double-Precision Floating-Point Values
case NN_minsd: // Return Minimum Scalar Double-Precision Floating-Point Value
case NN_movapd: // Move Aligned Packed Double-Precision Floating-Point Values
case NN_movdq2q: // Move Quadword from XMM to MMX Register
case NN_movdqa: // Move Aligned Double Quadword
case NN_movdqu: // Move Unaligned Double Quadword
case NN_movhpd: // Move High Packed Double-Precision Floating-Point Values
case NN_movlpd: // Move Low Packed Double-Precision Floating-Point Values
case NN_movmskpd: // Extract Packed Double-Precision Floating-Point Sign Mask
case NN_movntdq: // Store Double Quadword Using Non-Temporal Hint
case NN_movnti: // Store Doubleword Using Non-Temporal Hint
case NN_movntpd: // Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
case NN_movq2dq: // Move Quadword from MMX to XMM Register
case NN_movsd: // Move Scalar Double-Precision Floating-Point Values
case NN_movupd: // Move Unaligned Packed Double-Precision Floating-Point Values
case NN_mulpd: // Multiply Packed Double-Precision Floating-Point Values
case NN_mulsd: // Multiply Scalar Double-Precision Floating-Point Values
case NN_orpd: // Bitwise Logical OR of Double-Precision Floating-Point Values
case NN_paddq: // Add Packed Quadword Integers
case NN_pause: // Spin Loop Hint
case NN_pmuludq: // Multiply Packed Unsigned Doubleword Integers
case NN_pshufd: // Shuffle Packed Doublewords
case NN_pshufhw: // Shuffle Packed High Words
case NN_pshuflw: // Shuffle Packed Low Words
case NN_pslldq: // Shift Double Quadword Left Logical
case NN_psrldq: // Shift Double Quadword Right Logical
case NN_psubq: // Subtract Packed Quadword Integers
case NN_punpckhqdq: // Unpack High Data
case NN_punpcklqdq: // Unpack Low Data
case NN_shufpd: // Shuffle Packed Double-Precision Floating-Point Values
case NN_sqrtpd: // Compute Square Roots of Packed Double-Precision Floating-Point Values
case NN_sqrtsd: // Compute Square Rootof Scalar Double-Precision Floating-Point Value
case NN_subpd: // Subtract Packed Double-Precision Floating-Point Values
case NN_subsd: // Subtract Scalar Double-Precision Floating-Point Values
case NN_ucomisd: // Unordered Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS
case NN_unpckhpd: // Unpack and Interleave High Packed Double-Precision Floating-Point Values
case NN_unpcklpd: // Unpack and Interleave Low Packed Double-Precision Floating-Point Values
case NN_xorpd: // Bitwise Logical OR of Double-Precision Floating-Point Values
// AMD syscall/sysret instructions
case NN_syscall: // Low latency system call
case NN_sysret: // Return from system call
// AMD64 instructions
case NN_swapgs: // Exchange GS base with KernelGSBase MSR
// New Pentium instructions (SSE3)
case NN_movddup: // Move One Double-FP and Duplicate
case NN_movshdup: // Move Packed Single-FP High and Duplicate
case NN_movsldup: // Move Packed Single-FP Low and Duplicate
// Missing AMD64 instructions
case NN_movsxd: // Move with Sign-Extend Doubleword
case NN_cmpxchg16b: // Compare and Exchange 16 Bytes
// SSE3 instructions
case NN_addsubpd: // Add /Sub packed DP FP numbers
case NN_addsubps: // Add /Sub packed SP FP numbers
case NN_haddpd: // Add horizontally packed DP FP numbers
case NN_haddps: // Add horizontally packed SP FP numbers
case NN_hsubpd: // Sub horizontally packed DP FP numbers
case NN_hsubps: // Sub horizontally packed SP FP numbers
case NN_monitor: // Set up a linear address range to be monitored by hardware
case NN_mwait: // Wait until write-back store performed within the range specified by the MONITOR instruction
case NN_fisttp: // Store ST in intXX (chop) and pop
case NN_lddqu: // Load unaligned integer 128-bit
// SSSE3 instructions
case NN_psignb: // Packed SIGN Byte
case NN_psignw: // Packed SIGN Word
case NN_psignd: // Packed SIGN Doubleword
case NN_pshufb: // Packed Shuffle Bytes
case NN_pmulhrsw: // Packed Multiply High with Round and Scale
case NN_pmaddubsw: // Multiply and Add Packed Signed and Unsigned Bytes
case NN_phsubsw: // Packed Horizontal Subtract and Saturate
case NN_phaddsw: // Packed Horizontal Add and Saturate
case NN_phaddw: // Packed Horizontal Add Word
case NN_phaddd: // Packed Horizontal Add Doubleword
case NN_phsubw: // Packed Horizontal Subtract Word
case NN_phsubd: // Packed Horizontal Subtract Doubleword
case NN_palignr: // Packed Align Right
case NN_pabsb: // Packed Absolute Value Byte
case NN_pabsw: // Packed Absolute Value Word
case NN_pabsd: // Packed Absolute Value Doubleword
// VMX instructions
case NN_vmcall: // Call to VM Monitor
case NN_vmclear: // Clear Virtual Machine Control Structure
case NN_vmlaunch: // Launch Virtual Machine
case NN_vmresume: // Resume Virtual Machine
case NN_vmptrld: // Load Pointer to Virtual Machine Control Structure
case NN_vmptrst: // Store Pointer to Virtual Machine Control Structure
case NN_vmread: // Read Field from Virtual Machine Control Structure
case NN_vmwrite: // Write Field from Virtual Machine Control Structure
case NN_vmxoff: // Leave VMX Operation
case NN_vmxon: // Enter VMX Operation
return false;
break;
default:
msg("ERROR: Unknown instruction opcode at %x : %s\n", this->GetAddr(),
this->GetDisasm());
break;
} // end switch on opcode
return true;
} // end SMPInstr::BuildRTL()
// Iterate through all reg transfers and call SyncRTLDefUse for each.
void SMPInstr::SyncAllRTs(void) {
for (size_t index = 0; index < this->RTL.GetCount(); ++index) {
this->SyncRTLDefUse(this->RTL.GetRT(index));
}
return;
} // end of SMPInstr:SyncAllRTs()
// Ensure that each operand of the RTL is found in the appropriate DEF or USE list.
void SMPInstr::SyncRTLDefUse(SMPRegTransfer *CurrRT) {
// The Guard expression and ExtraKills are almost never represented in the DEF and USE
// lists. When they are, they are added in MDFixupDefUseLists(), so we ignore them here.
// The only DEFs should come from left operands of SMP_ASSIGN operators, i.e. the effects
// of register transfers.
op_t LeftOp, RightOp;
set<DefOrUse, LessDefUse>::iterator CurrDef, CurrUse;
bool DebugFlag = false;
#if SMP_VERBOSE_DEBUG_BUILD_RTL
DebugFlag |= (0 == strcmp("__libc_csu_fini", this->BasicBlock->GetFunc()->GetFuncName()));
#endif
if (DebugFlag) {
msg("SyncRTLDefUse entered. Dump of USE list:\n");
this->Uses.Dump();
}
LeftOp = CurrRT->GetLeftOperand();
if (SMP_ASSIGN == CurrRT->GetOperator()) {
assert(o_void != LeftOp.type);
assert(o_imm != LeftOp.type);
CurrDef = this->Defs.FindRef(LeftOp);
if (CurrDef == this->GetLastDef() && !LeftOp.is_reg(R_ip)) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL
msg("WARNING: DEF not found for SMP_ASSIGN in %s ; added op:", this->GetDisasm());
PrintOperand(LeftOp);
msg("\n");
#endif
this->Defs.SetRef(LeftOp, CurrRT->GetOperatorType());
}
}
else { // not SMP_ASSIGN; left operand should be a USE
if (o_void != LeftOp.type) {
CurrUse = this->Uses.FindRef(LeftOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
msg("WARNING: USE not found for ");
PrintOperand(LeftOp);
msg(" in %s ; added\n", this->GetDisasm());
#endif
this->Uses.SetRef(LeftOp);
}
}
}
if (!CurrRT->HasRightSubTree()) {
RightOp = CurrRT->GetRightOperand(); // right operand should be a USE
if (o_void != RightOp.type) {
CurrUse = this->Uses.FindRef(RightOp);
if (CurrUse == this->GetLastUse()) {
#if SMP_VERBOSE_DEBUG_BUILD_RTL_DEF_USE
msg("WARNING: USE not found for ");
PrintOperand(RightOp);
msg(" in %s ; added\n", this->GetDisasm());
#endif
this->Uses.SetRef(RightOp);
}
}
}
else { // recurse into right subtree
this->SyncRTLDefUse(CurrRT->GetRightTree());
}
return;
} // end of SMPInstr::SyncRTLDefUse()
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
// SetOperatorType - set the type of the operator, take into account the speculative (profiler) status
void SMPRegTransfer::SetOperatorType(SMPOperandType OpType, const SMPInstr* Instr)
{
SMPOperandType OldType=RTop.type;
SMPOperandType NewType=OpType;
if(Instr->GetBlock()->GetFunc()->GetIsSpeculative())
{
NewType=(SMPOperandType)(((int)NewType) | PROF_BASE);
if(!IsProfDerived(OldType))
RTop.NonSpeculativeType=OldType;
}
RTop.type = NewType;
} // end of SMPRegTransfer::SetOperatorType
// Update the memory source operands with to have the new type
void SMPInstr::UpdateMemLoadTypes(SMPOperandType newType)
{
bool MemSrc = false;
op_t Opnd;
for (int i = 0; i < UA_MAXOP; ++i)
{
Opnd = SMPcmd.Operands[i];
optype_t CurrType = Opnd.type;
if (this->features & UseMacros[i]) // USE
{
MemSrc = ((CurrType == o_mem) || (CurrType == o_phrase) || (CurrType == o_displ));
if (MemSrc)
{
set<DefOrUse, LessDefUse>::iterator use=this->FindUse(Opnd);
SMPOperandType type= use->GetType();
assert(newType==(NUMERIC|PROF_BASE));
switch(type)
{
case UNINIT:
case CODEPTR:
this->SetUseType(Opnd,newType);
break;
case POINTER:
this->SetUseType(Opnd, (SMPOperandType)(UNKNOWN|PROF_BASE));
break;
default:
break;
}
}
}
}
return ;
}