6 ConstantsClass
, FunctionsClass
, PrefixTreeClass
, ResourcesClass
, TypesClass
;
16 pAddress
, pMaxAddress
: Integer;
18 pInstructions
, pOperands
: TPrefixTree
;
19 pOldState
, pState
: THardwareState
;
20 pOnOperand
, pOnState
: TChangeEvent
;
21 function pErrorSet
: Boolean; virtual;
22 function pInstFromName(Name
: String; var Care
: Boolean): TInstruction
; virtual;
23 function pOperandAt(Input
: String; Position
: Integer): TOperandType
; virtual;
24 function pOperandToType(Input
: String): TOperandType
; virtual;
25 function pParseInstr(var Input
: String; InType
: Integer): TStrings
; virtual;
26 function pParseOperand(Input
: String): TStrings
; virtual;
27 function pTranslateOperands(Input
: String): String; virtual;
28 function pTranslateInput(Input
: TStrings
; var Tree
: TPrefixTree
; var Position
: Integer): Boolean; virtual;
29 function pTypeToDesc(Input
: TOperandType
): TStrings
; virtual;
30 function pTypeToOperands(Input
: TOperandType
): TStrings
; virtual;
31 function pTStringsToInst(Input
: TStrings
; Last
: Integer): String; virtual;
32 procedure pAddOperandByRecord(Input
: POperandRecord
); virtual;
33 procedure pSetError(Input
: String = GLOB_NO_ERROR
; Description
: String = ''); virtual;
34 procedure pSetState(Input
: THardwareState
); virtual;
36 constructor Create
; virtual;
37 function DescriptionsByPrefix(Prefix
: String): TStrings
; virtual;
38 function InstructionByName(Name
: String): TInstruction
; virtual;
39 function InstructionsByPrefix(Prefix
: String): TStrings
; virtual;
40 function OperandAdd(Operand
: String): Boolean; virtual;
41 function OperandRemove(Operand
: String): Boolean; virtual;
42 function ValidateInstruction(Instruction
: TInstruction
): Boolean; overload
; virtual;
43 function ValidateInstruction(Name
: String): Boolean; overload
; virtual;
44 function ValidateOperand(Operand
: String): Boolean; virtual;
45 procedure InitializeState
; virtual;
46 procedure InitializeOperands
; virtual;
47 destructor Destroy
; override;
48 property LastError
: String read pError
;
49 property Address
: Integer read pAddress write pAddress default
0;
50 property MaxAddress
: Integer read pMaxAddress write pMaxAddress default
0;
51 property OldState
: THardwareState read pOldState write pOldState
;
52 property OnOperand
: TChangeEvent read pOnOperand write pOnOperand
;
53 property OnState
: TChangeEvent read pOnState write pOnState
;
54 property Operands
: TPrefixTree read pOperands
;
55 property State
: THardwareState read pState write pSetState
;
63 pName
, pCode
, pDescription
: String;
66 function pGetCode
: String;
67 procedure pSetCode(Code
: String);
69 constructor Create
; virtual;
70 function Execute
: Boolean; virtual;
71 property Hardware
: THardware read pHardware write pHardware
;
72 property Name
: String read pName write pName
;
73 property Code
: String read pGetCode write pSetCode
;
74 property Branch
: TBranchType read pBranch write pBranch
;
75 property BranchAddress
: String read pAddr write pAddr
;
76 property Description
: String read pDescription write pDescription
;
81 function CompareStateCondition(Hardware
: THardware
; Position
: Integer): Boolean;
82 function CompareStateException(Hardware
: THardware
; Position
: Integer): Boolean;
83 function CompareStateFlag(Hardware
: THardware
; Position
: Integer): Boolean;
84 function CompareStateMask(Hardware
: THardware
; Position
: Integer): Boolean;
85 function CompareStatePrecision(Hardware
: THardware
): Boolean;
86 function CompareStateRound(Hardware
: THardware
): Boolean;
87 function CompareStateStack(Hardware
: THardware
; Position
: Integer): Boolean;
88 function CompareStateTag(Hardware
: THardware
; Position
: Integer): Boolean;
89 function GetCondition(State
: THardwareState
; Position
: Integer): Boolean;
90 function GetException(State
: THardwareState
; Position
: Integer): Boolean;
91 function GetFlag(State
: THardwareState
; Position
: Integer): Boolean;
92 function GetMask(State
: THardwareState
; Position
: Integer): Boolean;
93 function GetPrecision(State
: THardwareState
): Integer;
94 function GetRound(State
: THardwareState
): Integer;
95 function GetTag(State
: THardwareState
; Position
: Integer): Integer;
96 procedure SetCondition(var State
: THardwareState
; Position
: Integer; Condition
: Boolean);
97 procedure SetException(var State
: THardwareState
; Position
: Integer; Exception
: Boolean);
98 procedure SetFlag(var State
: THardwareState
; Position
: Integer; Flag
: Boolean);
99 procedure SetMask(var State
: THardwareState
; Position
: Integer; Mask
: Boolean);
100 procedure SetPrecision(var State
: THardwareState
; Precision
: Integer);
101 procedure SetRound(var State
: THardwareState
; Round
: Integer);
102 procedure SetTag(var State
: THardwareState
; Position
, Tag
: Integer);
106 // ************************************************************************** //
107 // * THardwareState implementation * //
108 // ************************************************************************** //
110 function THardware
.pErrorSet
: Boolean;
112 Result
:= not(pError
= GLOB_NO_ERROR
);
115 function THardware
.pInstFromName(Name
: String; var Care
: Boolean
122 linst
: PInstructionRecord
;
123 loper
: POperandRecord
;
130 lstrings
:= pParseInstr(Name
, INTYPE_INSTRUCTION
);
131 if pErrorSet
then Exit
;
133 while pTranslateInput(lstrings
, ltree
, i
) do;
134 if pErrorSet
then Exit
;
137 linst
:= PInstructionrecord(ltree
.Data
);
138 Result
:= TInstruction
.Create
;
140 Result
.Code
:= linst
^.Code
;
141 Result
.Description
:= linst
^.Description
;
142 Result
.Branch
:= linst
^.Branch
;
143 Result
.Hardware
:= Self
;
144 for i
:= 1 to (Length(lstrings
) - 1) do
146 if IsAddress(lstrings
[i
]) then
148 if (Result
.Branch
= BRANCH_BRANCH
) then
149 Result
.BranchAddress
:= lstrings
[i
];
152 ltree
:= pOperands
.GetDescendant(lstrings
[i
]);
153 loper
:= POperandRecord(ltree
.Data
);
154 lcode
:= loper
^.Code
;
155 llength
:= Length(Result
.Code
);
156 if (llength
> 0) and (Length(lcode
) > 0) then
158 lcode
[1] := Chr(Ord(lcode
[1]) xor Ord(Result
.Code
[llength
]));
159 Result
.Code
:= RemoveCharacter(Result
.Code
);
161 Result
.Code
:= Result
.Code
+ lcode
;
168 function THardware
.pOperandAt(Input
: String; Position
: Integer): TOperandType
;
173 if not(Position
> 0) then Exit
;
174 for i
:= 1 to Length(Input
) do
176 if (Position
= 0) then
181 if (Input
[i
] = FPU_SPACE
) then Position
:= Position
- 1;
185 function THardware
.pOperandToType(Input
: String): TOperandType
;
189 if IsAddress(Input
) then
191 Result
:= FPU_OPERAND_ADDR
;
194 ltree
:= pOperands
.GetDescendant(Input
);
195 if ValidPrefixTree(ltree
) then
196 Result
:= POperandRecord(ltree
.Data
)^.OperandType
199 pSetError(INST_OPER_UNKNOWN
, Input
);
200 Result
:= FPU_OPERAND_ERROR
;
204 function THardware
.pParseInstr(var Input
: String; InType
: Integer): TStrings
;
210 SetLength(Result
, 1);
214 pSetError(INST_NONE
);
217 lspace
:= (Input
[Length(Input
)] = ' ');
218 if not(InType
= INTYPE_DESCRIPTION
) then
219 for i
:= 1 to Length(Input
) do
220 if (Input
[i
] in CHARS_CONTROL
) then
222 pSetError(INST_CHAR_INVALID
, Input
[i
]);
225 Input
:= TrimCharacter(Input
, ' ');
226 Input
:= OmmitEverywhere(Input
, '(', ' ');
227 Input
:= OmmitEverywhere(Input
, ')', ' ');
228 Input
:= OmmitEverywhere(Input
, ',', ' ');
229 Input
:= NeutralizeDoubles(Input
, ' ');
230 Input
:= UpperCase(Input
);
233 pSetError(INST_NONE
);
237 Result
:= MergeStringTStrings(
238 lname
, ParseToStrings(PChar(ParseFirst(lname
, ' ')), ','));
239 if ((Intype
= INTYPE_DESCRIPTION
) or (InType
= INTYPE_PREFIX
)) and
240 (Length(Result
) = 1) and lspace
then
241 Result
:= MergeTStringsString(Result
, '');
244 function THardware
.pParseOperand(Input
: String): TStrings
;
248 Input
:= TrimCharacter(Input
, ' ');
249 Input
:= OmmitEverywhere(Input
, OPER_SEP
, ' ');
250 Input
:= UpperCase(Input
);
251 SetLength(Result
, 2);
252 Result
:= ParseToStrings(PChar(Input
), OPER_SEP
);
253 if not(Length(Result
) = 2) then
255 pSetError(INST_OPER_TYPE_INVALID
, Input
);
258 for i
:= 0 to (Length(Result
[0]) - 1) do
259 if (Result
[0][i
] in CHARS_CONTROL
) then
261 pSetError(INST_CHAR_INVALID
, Result
[0][i
]);
264 if ValidPrefixTree(pOperands
.GetDescendant(Result
[0])) then
266 pSetError(INST_OPER_NAME_EXISTS
, Result
[0]);
269 for i
:= 0 to (Length(sOperandOrdinals
) - 1) do
270 if (sOperandOrdinals
[i
].Name
= Result
[1]) then Exit
;
271 pSetError(INST_OPER_TYPE_UNKNOWN
, Result
[1]);
274 function THardware
.pTranslateOperands(Input
: String): String;
279 Result
:= ParseBeforeFirst(Input
, FPU_SPACE
);
281 ltype
:= pOperandAt(Input
, i
);
282 if not(ltype
= #0) then Result
:= Result
+ ' ' + pTypeToDesc(ltype
)[0];
285 ltype
:= pOperandAt(Input
, i
);
286 if (ltype
= #0) then Break
;
287 Result
:= Result
+ ',' + pTypeToDesc(ltype
)[0];
291 function THardware
.pTranslateInput(Input
: TStrings
; var Tree
: TPrefixTree
;
292 var Position
: Integer): Boolean;
298 if not(Length(Input
) > 0) then Exit
;
299 if (Position
< 0) then Exit
;
300 if (Position
= 0) then
302 ltree
:= pInstructions
;
306 if (Position
= Length(Input
)) then
308 if not ValidPrefixTree(ltree
) then
310 pSetError(INST_OPER_NOT_ENOUGH
);
313 Position
:= Position
+ 1;
315 if not(Position
< Length(Input
)) then Exit
;
316 if (ltree
= nil) then Exit
;
317 if ValidPrefixTree(ltree
) and (Length(ltree
.GetAllDescendants
) = 1) then
319 pSetError(INST_OPER_TOO_MANY
);
322 if not(Position
= 0) then
324 ltype
:= pOperandToType(Input
[Position
]);
325 if (ltype
= FPU_OPERAND_ERROR
) then
327 pSetError(INST_OPER_UNKNOWN
, Input
[Position
]);
330 if (Position
= 1) then ltree
:= ltree
.GetDescendant(ltype
)
331 else ltree
:= ltree
.GetDescendant(FPU_SPACE
+ ltype
);
332 if (ltree
= nil) then
334 pSetError(INST_OPER_INVALID
);
340 ltree
:= ltree
.GetDescendant(Input
[0] + FPU_SPACE
);
341 if (ltree
= nil) then
343 pSetError(INST_INST_UNKNOWN
, Input
[0]);
346 if (Length(Input
) = 1) then
348 ltree
:= ltree
.GetDescendant(FPU_OPERAND_NONE
);
349 if not ValidPrefixTree(ltree
) then
351 pSetError(INST_OPER_NOT_ENOUGH
);
356 Position
:= Position
+ 1;
361 function THardware
.pTypeToDesc(Input
: TOperandType
): TStrings
;
365 SetLength(Result
, 1);
366 Result
[0] := '<' + sOperandTypes
[0].Description
+ '>';
367 for i
:= 1 to (Length(sOperandTypes
) - 1) do
368 if (sOperandTypes
[i
].OperandType
= Input
) then
370 Result
[0] := '<' + sOperandTypes
[i
].Description
+ '>';
375 function THardware
.pTypeToOperands(Input
: TOperandType
): TStrings
;
378 ltrees
: TPrefixTrees
;
379 loperand
: POperandRecord
;
381 SetLength(Result
, 0);
382 ltrees
:= pOperands
.GetAllDescendants
;
383 for i
:= 0 to (Length(ltrees
) - 1) do
385 loperand
:= POperandRecord(ltrees
[i
].Data
);
386 if (loperand
^.OperandType
= Input
) then
387 Result
:= MergeTStringsString(Result
, loperand
^.Name
);
389 if (Input
= FPU_OPERAND_ADDR
) then Result
:= MergeTStringsString(Result
,
390 '<0 - ' + ZeroPaddedInteger(MaxAddress
) + '>');
391 if (Length(Result
) = 0) then pSetError(INST_OPER_UNKNOWN
);
394 function THardware
.pTStringsToInst(Input
: TStrings
; Last
: Integer): String;
399 if not(Length(Input
) > 0) then Exit
;
400 if not(Last
< Length(Input
)) then Exit
;
402 if (Last
< 0) then Exit
;
403 Result
:= Result
+ ' ';
404 for i
:= 1 to Last
do
405 if not(Input
[i
] = '') then
406 Result
:= Result
+ Input
[i
] + ',';
409 procedure THardware
.pAddOperandByRecord(Input
: POperandRecord
);
411 if not(Input
^.Default
= '') then
414 Data
:= GetMemory(Length(Default
));
415 Move(PChar(Default
)[0], Data
^, Length(Default
));
416 Code
:= Code
+ AddressToString(Data
);
418 pOperands
.Add(Input
^.Name
, Input
);
421 procedure THardware
.pSetError(Input
, Description
: String);
424 if not(Description
= '') then pError
:= pError
+ ': "' + Description
+ '"';
427 procedure THardware
.pSetState(Input
: THardwareState
);
430 if not(@OnState
= nil) then OnState(Self
);
433 constructor THardware
.Create
;
439 pInstructions
:= TPrefixTree
.Create
;
440 for i
:= 0 to (Length(sInstructions
) - 1) do
441 pInstructions
.Add(sInstructions
[i
].Name
, @sInstructions
[i
]);
445 function THardware
.DescriptionsByPrefix(Prefix
: String): TStrings
;
448 linst
: PInstructionRecord
;
449 linstructions
, lnames
, lstrings
: TStrings
;
452 ltrees
: TPrefixTrees
;
454 SetLength(Result
, 0);
455 SetLength(lnames
, 0);
456 SetLength(lstrings
, 0);
457 SetLength(ltrees
, 0);
458 linstructions
:= InstructionsByPrefix(Prefix
);
459 for i
:= 0 to (Length(linstructions
) - 1) do
461 lstrings
:= pParseInstr(linstructions
[i
], INTYPE_DESCRIPTION
);
463 while pTranslateInput(lstrings
, ltree
, lpos
) do;
464 ltrees
:= ltree
.GetAllDescendants
;
465 for j
:= 0 to (Length(ltrees
) - 1) do
467 lname
:= PInstructionRecord(ltrees
[j
].Data
)^.Name
;
468 lnames
:= RemoveExactString(lnames
, lname
);
469 lnames
:= MergeTStringsString(lnames
, lname
);
472 for i
:= 0 to (Length(lnames
) - 1) do
474 linst
:= PInstructionRecord(pInstructions
.GetDescendant(lnames
[i
]).Data
);
475 lname
:= pTranslateOperands(linst
^.Name
) + ' - ' + linst
^.Description
;
476 RemoveExactString(Result
, lname
);
477 Result
:= MergeTStringsString(Result
, lname
);
482 function THardware
.InstructionByName(Name
: String): TInstruction
;
487 Result
:= pInstFromName(Name
, lcare
);
490 function THardware
.InstructionsByPrefix(Prefix
: String): TStrings
;
493 lstrings
, loperands
: TStrings
;
494 lprefix
, lopers
: String;
496 ltrees
: TPrefixTrees
;
497 linst
: PInstructionRecord
;
500 SetLength(Result
, 0);
501 SetLength(loperands
, 0);
502 SetLength(ltrees
, 0);
503 lstrings
:= pParseInstr(Prefix
, INTYPE_PREFIX
);
504 if not(lstrings
[Length(lstrings
)] = '') then
505 lstrings
[Length(lstrings
) - 1] := '';
507 while pTranslateInput(lstrings
, ltree
, lpos
) do;
508 if (lpos
= 0) and (Length(lstrings
) > 1) then Exit
;
509 ltrees
:= ltree
.GetAllDescendants
;
510 lprefix
:= pTStringsToInst(lstrings
, lpos
- 1);
511 for i
:= 0 to (Length(ltrees
) - 1) do
513 linst
:= PInstructionRecord(ltrees
[i
].Data
);
516 if IsPrefixOf(Prefix
, linst
^.Name
) then
518 lopers
:= ParseBeforeFirst(linst
^.Name
, FPU_SPACE
) + ' ';
519 Result
:= RemoveExactString(Result
, lopers
);
520 Result
:= MergeTStringsString(Result
, lopers
);
525 loperands
:= pTypeToOperands(pOperandAt(linst
^.Name
, lpos
));
526 if (Length(loperands
) = 0) then
527 loperands
:= pTypeToDesc(pOperandAt(linst
^.Name
, lpos
));
528 loperands
:= CartesianOfStrings(lprefix
, loperands
);
529 for j
:= 0 to (Length(loperands
) - 1) do
530 if IsPrefixOf(Prefix
, loperands
[j
]) then
532 if not(pOperandAt(linst
^.Name
, lpos
+ 1) = #0) then
533 loperands
[j
] := loperands
[j
] + ',';
534 Result
:= RemoveExactString(Result
, loperands
[j
]);
535 Result
:= MergeTStringsString(Result
, loperands
[j
]);
544 function THardware
.OperandAdd(Operand
: String): Boolean;
548 lrecord
: POperandRecord
;
552 lstrings
:= pParseOperand(Operand
);
553 if pErrorSet
then Exit
;
554 for i
:= 0 to (Length(sOperandOrdinals
) - 1) do
555 with sOperandOrdinals
[i
] do
556 if (Name
= lstrings
[1]) and not(Default
= '') then
559 lrecord
^ := sOperandOrdinals
[i
];
560 lrecord
^.Name
:= lstrings
[0];
561 pAddOperandByRecord(lrecord
);
565 if Result
and not(@OnOperand
= nil) then OnOperand(Self
);
568 function THardware
.OperandRemove(Operand
: String): Boolean;
575 Operand
:= UpperCase(TrimCharacter(Operand
, ' '));
576 for i
:= 0 to (Length(Operand
) - 1) do
577 if (Operand
[i
] in CHARS_CONTROL
) then
579 pSetError(INST_CHAR_INVALID
, Operand
[i
]);
582 ltree
:= pOperands
.GetDescendant(Operand
);
583 if ValidPrefixTree(ltree
) then
585 Dispose(POperandRecord(ltree
.Data
));
586 pOperands
.Remove(Operand
);
590 pSetError(INST_OPER_NAME_UNKNOWN
, Operand
);
591 if Result
and not(@OnOperand
= nil) then OnOperand(Self
);
594 function THardware
.ValidateInstruction(Instruction
: TInstruction
): Boolean;
598 Result
:= ValidateInstruction(Instruction
.Name
);
601 linst
:= InstructionByName(Instruction
.Name
);
602 if not(Instruction
.Code
= linst
.Code
) then Instruction
.Code
:= linst
.Code
;
607 function THardware
.ValidateInstruction(Name
: String): Boolean;
612 pInstFromName(Name
, lcare
);
616 function THardware
.ValidateOperand(Operand
: String): Boolean;
619 pParseOperand(Operand
);
620 Result
:= not pErrorSet
;
623 procedure THardware
.InitializeState
;
626 lstate
: THardwareState
;
631 fnsave [lstate.FPUState
]
634 pop dword ptr [lstate.EFlags
]
638 lstate
.FPUState
.ST
[i
] := 0;
643 procedure THardware
.InitializeOperands
;
648 pOperands
:= TPrefixTree
.Create
;
649 for i
:= 0 to (Length(sOperands
) - 1) do
650 pAddOperandByRecord(@sOperands
[i
]);
651 if not(@OnOperand
= nil) then OnOperand(Self
);
654 destructor THardware
.Destroy
;
660 // ************************************************************************** //
661 // * TInstruction implementation * //
662 // ************************************************************************** //
664 function TInstruction
.pGetCode
: String;
666 Result
:= RemoveCharacter(pCode
);
669 procedure TInstruction
.pSetCode(Code
: String);
671 pCode
:= Code
+ INST_OPCODE_RET
;
674 constructor TInstruction
.Create
;
679 Branch
:= BRANCH_NORMAL
;
682 function TInstruction
.Execute
: Boolean;
684 lstate
: THardwareState
;
686 if (Branch
= BRANCH_UNSUPPORTED
) then
689 LogWrite(INST_INST_UNSUPPORTED
, True);
692 lstate
:= pHardware
.State
;
697 push [TInstruction
(eax).pCode
]
698 frstor [lstate.FPUState
]
699 push dword ptr [lstate.EFlags
]
700 push dword ptr [lstate.Reg_EAX
]
707 pop dword ptr [lstate.Reg_EAX
]
708 pop dword ptr [lstate.EFlags
]
709 fnsave [lstate.FPUState
]
713 pHardware
.OldState
:= pHardware
.State
;
714 pHardware
.State
:= lstate
;
717 // ************************************************************************** //
718 // * Static Functions implementation * //
719 // ************************************************************************** //
721 function CompareStateCondition(Hardware
: THardware
; Position
: Integer
726 lcondition
:= GetCondition(Hardware
.State
, Position
);
727 Result
:= (lcondition
= GetCondition(Hardware
.pOldState
, Position
));
730 function CompareStateException(Hardware
: THardware
; Position
: Integer
735 lexception
:= GetException(Hardware
.State
, Position
);
736 Result
:= (lexception
= GetException(Hardware
.OldState
, Position
));
739 function CompareStateFlag(Hardware
: THardware
; Position
: Integer): Boolean;
742 Result
:= (GetFlag(State
, Position
) = GetFlag(pOldState
, Position
));
745 function CompareStateMask(Hardware
: THardware
; Position
: Integer): Boolean;
749 lexception
:= GetMask(Hardware
.State
, Position
);
750 Result
:= (lexception
= GetMask(Hardware
.OldState
, Position
));
753 function CompareStatePrecision(Hardware
: THardware
): Boolean;
757 lprecision
:= GetPrecision(Hardware
.State
);
758 Result
:= (lprecision
= GetPrecision(Hardware
.OldState
));
761 function CompareStateRound(Hardware
: THardware
): Boolean;
763 Result
:= (GetRound(Hardware
.State
) = GetRound(Hardware
.OldState
));
766 function CompareStateStack(Hardware
: THardware
; Position
: Integer): Boolean;
771 if (Position
< 0) or (Position
> 7) then Exit
;
772 lsecond
:= @Hardware
.OldState
.FPUState
.ST
[Position
];
773 with Hardware
.State
.FPUState
do
774 Result
:= StringCompare(@ST
[Position
], lsecond
, SizeOf(ST
[Position
]));
777 function CompareStateTag(Hardware
: THardware
; Position
: Integer): Boolean;
781 ltag
:= GetTag(Hardware
.State
, Position
);
782 Result
:= (ltag
= GetTag(Hardware
.OldState
, Position
));
785 function GetCondition(State
: THardwareState
; Position
: Integer): Boolean;
788 if (Position
< 0) or (Position
> 3) then Exit
;
789 if (Position
= 3) then Position
:= 14
790 else Position
:= Position
+ 8;
791 Result
:= not((State
.FPUState
.StatusWord
and (1 shl Position
)) = 0);
794 function GetException(State
: THardwareState
; Position
: Integer): Boolean;
797 if (Position
< 0) or (Position
> 7) then Exit
;
798 Result
:= not((State
.FPUState
.StatusWord
and (1 shl Position
)) = 0);
801 function GetFlag(State
: THardwareState
; Position
: Integer): Boolean;
804 if (Position
< 0) or (Position
> 2) then Exit
;
809 Result
:= not((State
.EFlags
and (1 shl Position
)) = 0);
812 function GetMask(State
: THardwareState
; Position
: Integer): Boolean;
815 if (Position
< 0) or (Position
> 5) then Exit
;
816 Result
:= not((State
.FPUState
.ControlWord
and (1 shl Position
)) = 0);
819 function GetPrecision(State
: THardwareState
): Integer;
821 Result
:= (State
.FPUState
.ControlWord
shr 8) and 3;
824 function GetRound(State
: THardwareState
): Integer;
826 Result
:= (State
.FPUState
.ControlWord
shr 10) and 3;
829 function GetTag(State
: THardwareState
; Position
: Integer): Integer;
834 if (Position
< 0) or (Position
> 7) then Exit
;
835 with State
.FPUState
do
837 ltop
:= (Position
+ ((StatusWord
shr 11) and 7)) mod 8;
838 Result
:= (TagWord
shr (2 * ltop
)) and 3;
842 procedure SetCondition(var State
: THardwareState
; Position
: Integer;
845 if (Position
< 0) or (Position
> 7) then Exit
;
846 if (Position
= 3) then Position
:= 14
847 else Position
:= Position
+ 8;
848 with State
.FPUState
do
849 if Condition
then StatusWord
:= StatusWord
or (1 shl Position
)
850 else StatusWord
:= StatusWord
and not(1 shl Position
);
853 procedure SetException(var State
: THardwareState
; Position
: Integer;
856 if (Position
< 0) or (Position
> 7) then Exit
;
857 with State
.FPUState
do
858 if Exception
then StatusWord
:= StatusWord
or (1 shl Position
)
859 else StatusWord
:= StatusWord
and not(1 shl Position
);
862 procedure SetFlag(var State
: THardwareState
; Position
: Integer; Flag
: Boolean
865 if (Position
< 0) or (Position
> 2) then Exit
;
870 if Flag
then State
.EFlags
:= State
.EFlags
or (1 shl Position
)
871 else State
.EFlags
:= State
.EFlags
and not(1 shl Position
);
874 procedure SetMask(var State
: THardwareState
; Position
: Integer; Mask
: Boolean
877 if (Position
< 0) or (Position
> 5) then Exit
;
878 with State
.FPUState
do
879 if Mask
then ControlWord
:= ControlWord
or (1 shl Position
)
880 else ControlWord
:= ControlWord
and not(1 shl Position
);
883 procedure SetPrecision(var State
: THardwareState
; Precision
: Integer);
887 if (Precision
< 0) or (Precision
> 3) then Exit
;
888 with State
.FPUState
do
890 lcw
:= ControlWord
and not(3 shl 8);
891 ControlWord
:= lcw
or (Precision
shl 8);
895 procedure SetRound(var State
: THardwareState
; Round
: Integer);
899 if (Round
< 0) or (Round
> 3) then Exit
;
900 with State
.FPUState
do
902 lcw
:= ControlWord
and not(3 shl 10);
903 ControlWord
:= lcw
or (Round
shl 10);
907 procedure SetTag(var State
: THardwareState
; Position
, Tag
: Integer);
911 if (Position
< 0) or (Position
> 7) or (Tag
< 0) or (Tag
> 3) then Exit
;
912 with State
.FPUState
do
914 ltop
:= (Position
+ ((StatusWord
shr 11) and 7)) mod 8;
915 ltag
:= TagWord
and not(3 shl (2 * ltop
));
916 TagWord
:= ltag
or (Tag
shl (2 * ltop
));