+ rec.field(%esi) support

+ [esi+rec.field] support
This commit is contained in:
peter 1998-12-23 22:55:55 +00:00
parent f986459350
commit ce3e2aec84
3 changed files with 762 additions and 769 deletions

View File

@ -228,6 +228,8 @@ Type
Procedure OpPop(var _Operator:TExprOperator);
end;
{ Evaluate an expression string to a longint }
Function CalculateExpression(const expression: string): longint;
{---------------------------------------------------------------------}
{ String routines }
@ -546,6 +548,15 @@ Begin
end;
Function CalculateExpression(const expression: string): longint;
var
expr: TExprParse;
Begin
expr.Init;
CalculateExpression := expr.Evaluate(expression);
expr.Done;
end;
{*************************************************************************}
{ String conversions/utils }
{*************************************************************************}
@ -657,6 +668,7 @@ end;
'7': vs:=vs shl 3+7;
else
begin
Message(assem_f_error_converting_octal);
OctalToDec := '';
exit;
end;
@ -683,6 +695,7 @@ end;
vs:=vs shl 1+1
else
begin
Message(assem_f_error_converting_bin);
BinaryToDec := '';
exit;
end;
@ -719,6 +732,7 @@ end;
'F': vs:=vs shl 4+15;
else
begin
Message(assem_f_error_converting_hex);
HexToDec := '';
exit;
end;
@ -1788,7 +1802,11 @@ end;
end.
{
$Log$
Revision 1.16 1998-12-11 00:02:44 peter
Revision 1.17 1998-12-23 22:55:55 peter
+ rec.field(%esi) support
+ [esi+rec.field] support
Revision 1.16 1998/12/11 00:02:44 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.15 1998/11/17 00:26:11 peter

View File

@ -2426,17 +2426,6 @@ const
Function CalculateExpression(expression: string): longint;
var
expr: TExprParse;
Begin
expr.Init;
CalculateExpression := expr.Evaluate(expression);
expr.Done;
end;
Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{*********************************************************************}
{ PROCEDURE GetRecordOffsetSize }
@ -2445,7 +2434,7 @@ const
{ On entry actasmtoken should be equal to AS_DOT }
{*********************************************************************}
{ EXIT CONDITION: On exit the routine should point to either the }
{ AS_COMMA or AS_SEPARATOR token. }
{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. }
{ Warning: This is called recursively. }
{*********************************************************************}
var
@ -2466,24 +2455,12 @@ const
inc(offset,toffset);
size:=tsize;
Consume(AS_ID);
case actasmtoken of
AS_SEPARATOR,
AS_COMMA : exit;
AS_DOT : begin
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(offset,toffset);
size:=tsize;
end;
else
Begin
Message(assem_e_syntax_error);
repeat
consume(actasmtoken)
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
exit;
end;
end;
end
else
Begin
@ -2797,7 +2774,7 @@ const
Consume(AS_RPAREN)
else
Message(assem_e_invalid_scaling_value);
{ // .Field.Field ... or separator/comma // }
{ .Field.Field ... or separator/comma }
if actasmtoken in [AS_COMMA,AS_SEPARATOR] then
Begin
end
@ -3031,7 +3008,7 @@ const
End;
exit;
End;
{ // (reg ... // }
{ (reg ... }
AS_REGISTER: Begin
{ Check if there is already a base (mostly ebp,esp) than this is
not allowed,becuase it will give crashing code }
@ -3040,7 +3017,7 @@ const
instr.operands[operandnum].ref.base := findregister(actasmpattern);
Consume(AS_REGISTER);
{ can either be a register or a right parenthesis }
{ // (reg) // }
{ (reg) }
if actasmtoken=AS_RPAREN then Begin
Consume(AS_RPAREN);
if not (actasmtoken in [AS_COMMA,
@ -3053,7 +3030,7 @@ const
end;
exit;
end;
{ // (reg,reg .. // }
{ (reg,reg .. }
{ we need a comman here !! }
{ oops.. }
Consume(AS_COMMA);
@ -3098,7 +3075,7 @@ const
end;
end; {end case }
end;
{ // (, ... // }
{ (, ... }
AS_COMMA: { can either be scaling, or index }
Begin
Consume(AS_COMMA);
@ -3213,20 +3190,20 @@ const
expr: string;
lab: Pasmlabel;
hl: plabel;
tsize,
tsize,l,
toffset : longint;
Begin
tempstr := '';
expr := '';
case actasmtoken of
{ // Memory reference // }
AS_LPAREN:
AS_LPAREN: { Memory reference }
Begin
initAsmRef(instr);
BuildReference(instr);
end;
{ // Constant expression // }
AS_DOLLAR: Begin
AS_DOLLAR: { Constant expression }
Begin
Consume(AS_DOLLAR);
if not (instr.operands[operandnum].operandtype in [OPR_NONE,OPR_CONSTANT]) then
Message(assem_e_invalid_operand_type);
@ -3234,30 +3211,28 @@ const
instr.operands[operandnum].operandtype := OPR_CONSTANT;
instr.operands[operandnum].val :=BuildExpression;
end;
{ // Constant memory offset . // }
{ // This must absolutely be followed by ( // }
AS_HEXNUM,AS_INTNUM,AS_MINUS,
AS_BINNUM,AS_OCTALNUM,AS_PLUS:
Begin
{ Constant memory offset }
{ This must absolutely be followed by ( }
InitAsmRef(instr);
instr.operands[operandnum].ref.offset:=BuildRefExpression(False);
BuildReference(instr);
end;
{ // Call from memory address // }
AS_STAR: Begin
AS_STAR: { Call from memory address }
Begin
Consume(AS_STAR);
InitAsmRef(instr);
if not CreateVarInstr(instr,actasmpattern,operandnum) then
Message(assem_e_syn_opcode_operand);
end;
{ // A constant expression, or a Variable ref. // }
AS_ID: Begin
{ // Local label. // }
AS_ID: { A constant expression, or a Variable ref. }
Begin
{ Local label ? }
if (actasmpattern[1] ='.') and (actasmpattern[2] = 'L') then
Begin
Begin
delete(actasmpattern,1,1);
delete(actasmpattern,1,1);
delete(actasmpattern,1,2);
if actasmpattern = '' then
Message(assem_e_null_label_ref_not_allowed);
lab := labellist.search(actasmpattern);
@ -3274,26 +3249,25 @@ const
end;
end
else
Begin
{ the label does not exist, create it }
{ emit the opcode, but set that the }
{ label has not been emitted }
Begin
getlabel(hl);
labellist.insert(actasmpattern,hl,FALSE);
instr.operands[operandnum].operandtype := OPR_LABINSTR;
instr.operands[operandnum].hl := hl;
instr.labeled := TRUE;
end;
end;
Consume(AS_ID);
if not (actasmtoken in [AS_SEPARATOR,AS_COMMA]) then
Begin
Message(assem_e_syntax_error);
end;
end
else
{ probably a variable or normal expression }
{ or a procedure (such as in CALL ID) }
else
Begin
{ check if this is a label, if so then }
{ emit it as a label. }
@ -3323,10 +3297,8 @@ const
if assigned(procinfo._class) then
Begin
instr.operands[operandnum].operandtype := OPR_REFERENCE;
instr.operands[operandnum].ref.offset :=
procinfo.ESI_offset;
instr.operands[operandnum].ref.base :=
procinfo.framepointer;
instr.operands[operandnum].ref.offset := procinfo.ESI_offset;
instr.operands[operandnum].ref.base := procinfo.framepointer;
end
else
Message(assem_e_cannot_use___SELF_outside_methode);
@ -3337,14 +3309,12 @@ const
if lexlevel>normal_function_level then
Begin
instr.operands[operandnum].operandtype := OPR_REFERENCE;
instr.operands[operandnum].ref.offset :=
procinfo.framepointer_offset;
instr.operands[operandnum].ref.base :=
procinfo.framepointer;
instr.operands[operandnum].ref.offset := procinfo.framepointer_offset;
instr.operands[operandnum].ref.base := procinfo.framepointer;
end
else
Message(assem_e_cannot_use___OLDEBP_outside_nested_procedure);
end { endif actasmpattern = '__OLDEBP' }
end
else
{ check for direct symbolic names }
{ only if compiling the system unit }
@ -3362,23 +3332,32 @@ const
end;
{ constant expression? }
if (instr.operands[operandnum].operandtype=OPR_CONSTANT) then
instr.operands[operandnum].val := BuildExpression
begin
instr.operands[operandnum].val := BuildRefExpression(false);
previous_was_id:=FALSE;
{ indexing? }
if actasmtoken=AS_LPAREN then
begin
l:=instr.operands[operandnum].val;
instr.operands[operandnum].operandtype:=OPR_REFERENCE;
reset_reference(Instr.Operands[OperandNum].Ref);
Instr.Operands[OperandNum].Ref.Offset:=l;
BuildReference(instr);
end;
end
else
begin
expr := actasmpattern;
Consume(AS_ID);
case actasmtoken of
AS_LPAREN: Begin
{ indexing }
previous_was_id:=FALSE;
BuildReference(instr);
end;
AS_DOT : Begin
AS_DOT:
Begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(instr.operands[operandnum].ref.offset,toffset);
SetOperandSize(instr,operandnum,tsize);
end;
AS_SEPARATOR,AS_COMMA: ;
AS_SEPARATOR,
AS_COMMA: ;
else
Message(assem_e_syntax_error);
end; { end case }
@ -3387,9 +3366,9 @@ const
previous_was_id := FALSE;
end; { end if }
end; { end if }
end; { end this case }
{ // Register, a variable reference or a constant reference // }
AS_REGISTER: Begin
end;
AS_REGISTER: { Register, a variable reference or a constant reference }
Begin
{ save the type of register used. }
tempstr := actasmpattern;
Consume(AS_REGISTER);
@ -3401,12 +3380,12 @@ const
{ here we can have either an identifier }
{ or a constant, where either can be }
{ followed by a parenthesis... }
{ // Constant memory offset . // }
{ // This must absolutely be followed by ( // }
{ Constant memory offset . }
{ This must absolutely be followed by ( }
case actasmtoken of
AS_HEXNUM,AS_INTNUM,AS_MINUS,
AS_BINNUM,AS_OCTALNUM,AS_PLUS
: Begin
AS_BINNUM,AS_OCTALNUM,AS_PLUS:
Begin
instr.operands[operandnum].
ref.offset:=BuildRefExpression(False);
BuildReference(instr);
@ -3446,7 +3425,7 @@ const
end;
end; { end case }
end
{ // Simple register // }
{ Simple register }
else if (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA) then
Begin
if not (instr.operands[operandnum].operandtype in [OPR_NONE,OPR_REGISTER]) then
@ -3457,7 +3436,8 @@ const
else
Message1(assem_e_syn_register,tempstr);
end;
AS_SEPARATOR, AS_COMMA: ;
AS_SEPARATOR,
AS_COMMA: ;
else
Begin
Message(assem_e_syn_opcode_operand);
@ -3599,8 +3579,8 @@ const
asmtok := A_NONE; { assmume no prefix }
segreg := R_NO; { assume no segment override }
{ // prefix seg opcode // }
{ // prefix opcode // }
{ prefix seg opcode }
{ prefix opcode }
if findprefix(actasmpattern,asmtok) then
Begin
{ standard opcode prefix }
@ -3608,7 +3588,7 @@ const
instr.addprefix(asmtok);
Consume(AS_OPCODE);
end;
{ // opcode // }
{ opcode }
{ allow for newline as in gas styled syntax }
{ under DOS you get two AS_SEPARATOR !! }
while actasmtoken=AS_SEPARATOR do
@ -3625,11 +3605,11 @@ const
Begin
op := findopcode(actasmpattern);
instr.addinstr(op);
{ // Valid combination of prefix and instruction ? // }
{ Valid combination of prefix and instruction ? }
if (asmtok <> A_NONE) and (NOT CheckPrefix(asmtok,op)) then
Message1(assem_e_invalid_prefix_and_opcode,actasmpattern);
Consume(AS_OPCODE);
{ // Zero operand opcode ? // }
{ Zero operand opcode ? }
if actasmtoken in [AS_SEPARATOR,AS_END] then
exit
else
@ -3638,7 +3618,7 @@ const
repeat
case actasmtoken of
{ // Operand delimiter // }
{ Operand delimiter }
AS_COMMA: Begin
if operandnum > MaxOperands then
Message(assem_e_too_many_operands)
@ -3646,7 +3626,7 @@ const
Inc(operandnum);
Consume(AS_COMMA);
end;
{ // End of asm operands for this opcode // }
{ End of asm operands for this opcode }
AS_SEPARATOR,
AS_END : break;
else
@ -3969,7 +3949,11 @@ end.
{
$Log$
Revision 1.26 1998-12-11 00:03:42 peter
Revision 1.27 1998-12-23 22:55:56 peter
+ rec.field(%esi) support
+ [esi+rec.field] support
Revision 1.26 1998/12/11 00:03:42 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.25 1998/12/09 13:23:40 jonas

View File

@ -2006,18 +2006,6 @@ var
Function CalculateExpression(expression: string): longint;
var
expr: TExprParse;
Begin
expr.Init;
CalculateExpression := expr.Evaluate(expression);
expr.Done;
end;
Procedure GetRecordOffsetSize(const expr: string;var offset:longint;var size:longint);
{*********************************************************************}
{ PROCEDURE GetRecordOffsetSize }
@ -2026,7 +2014,7 @@ var
{ On entry actasmtoken should be equal to AS_DOT }
{*********************************************************************}
{ EXIT CONDITION: On exit the routine should point to either the }
{ AS_COMMA or AS_SEPARATOR token. }
{ ERROR RECOVER: read until AS_COMMA or AS_SEPARATOR token. }
{ Warning: This is called recursively. }
{*********************************************************************}
var
@ -2047,24 +2035,12 @@ var
inc(offset,toffset);
size:=tsize;
Consume(AS_ID);
case actasmtoken of
AS_SEPARATOR,
AS_COMMA : exit;
AS_DOT : begin
if actasmtoken=AS_DOT then
begin
GetRecordOffsetSize(expr,toffset,tsize);
inc(offset,toffset);
size:=tsize;
end;
else
Begin
Message(assem_e_syntax_error);
repeat
consume(actasmtoken)
until (actasmtoken = AS_SEPARATOR) or (actasmtoken = AS_COMMA);
exit;
end;
end;
end
else
Begin
@ -2091,8 +2067,8 @@ var
{ ERROR RECOVERY: Tries to find COMMA or SEPARATOR token by consuming }
{ invalid tokens. }
{*********************************************************************}
var tempstr: string;
expr: string;
var
tempstr,expr : string;
l,k : longint;
errorflag : boolean;
Begin
@ -2104,68 +2080,90 @@ var
inexpression := TRUE;
Repeat
Case actasmtoken of
AS_LPAREN: Begin
AS_LPAREN:
Begin
Consume(AS_LPAREN);
expr := expr + '(';
end;
AS_RPAREN: Begin
AS_RPAREN:
Begin
Consume(AS_RPAREN);
expr := expr + ')';
end;
AS_SHL: Begin
AS_SHL:
Begin
Consume(AS_SHL);
expr := expr + '<';
end;
AS_SHR: Begin
AS_SHR:
Begin
Consume(AS_SHR);
expr := expr + '>';
end;
AS_SLASH: Begin
AS_SLASH:
Begin
Consume(AS_SLASH);
expr := expr + '/';
end;
AS_MOD: Begin
AS_MOD:
Begin
Consume(AS_MOD);
expr := expr + '%';
end;
AS_STAR: Begin
AS_STAR:
Begin
Consume(AS_STAR);
expr := expr + '*';
end;
AS_PLUS: Begin
AS_PLUS:
Begin
Consume(AS_PLUS);
expr := expr + '+';
end;
AS_MINUS: Begin
AS_MINUS:
Begin
Consume(AS_MINUS);
expr := expr + '-';
end;
AS_AND: Begin
AS_AND:
Begin
Consume(AS_AND);
expr := expr + '&';
end;
AS_NOT: Begin
AS_NOT:
Begin
Consume(AS_NOT);
expr := expr + '~';
end;
AS_XOR: Begin
AS_XOR:
Begin
Consume(AS_XOR);
expr := expr + '^';
end;
AS_OR: Begin
AS_OR:
Begin
Consume(AS_OR);
expr := expr + '|';
end;
{ End of reference }
AS_RBRACKET: Begin
if not ErrorFlag then
BuildRefExpression := CalculateExpression(expr)
else
BuildRefExpression := 0;
Consume(AS_RBRACKET);
{ no longer in an expression }
inexpression := FALSE;
exit;
AS_INTNUM:
Begin
expr := expr + actasmpattern;
Consume(AS_INTNUM);
end;
AS_BINNUM:
Begin
expr:=expr+BinaryToDec(actasmpattern);
Consume(AS_BINNUM);
end;
AS_HEXNUM:
Begin
expr:=expr+HexToDec(actasmpattern);
Consume(AS_HEXNUM);
end;
AS_OCTALNUM:
Begin
expr:=expr+OctalToDec(actasmpattern);
Consume(AS_OCTALNUM);
end;
AS_ID:
Begin
@ -2188,31 +2186,16 @@ var
Message1(assem_e_invalid_const_symbol,tempstr);
end;
end;
AS_INTNUM: Begin
expr := expr + actasmpattern;
Consume(AS_INTNUM);
end;
AS_BINNUM: Begin
tempstr := BinaryToDec(actasmpattern);
if tempstr = '' then
Message(assem_f_error_converting_bin);
expr:=expr+tempstr;
Consume(AS_BINNUM);
end;
AS_HEXNUM: Begin
tempstr := HexToDec(actasmpattern);
if tempstr = '' then
Message(assem_f_error_converting_hex);
expr:=expr+tempstr;
Consume(AS_HEXNUM);
end;
AS_OCTALNUM: Begin
tempstr := OctalToDec(actasmpattern);
if tempstr = '' then
Message(assem_f_error_converting_octal);
expr:=expr+tempstr;
Consume(AS_OCTALNUM);
AS_RBRACKET: { End of reference }
Begin
if not ErrorFlag then
BuildRefExpression := CalculateExpression(expr)
else
BuildRefExpression := 0;
Consume(AS_RBRACKET);
{ no longer in an expression }
inexpression := FALSE;
exit;
end;
else
Begin
@ -2220,7 +2203,8 @@ var
if not errorflag then
Message(assem_e_invalid_constant_expression);
BuildRefExpression := 0;
if actasmtoken in [AS_COMMA,AS_SEPARATOR] then exit;
if actasmtoken in [AS_COMMA,AS_SEPARATOR] then
exit;
{ consume tokens until we find COMMA or SEPARATOR }
Consume(actasmtoken);
errorflag := TRUE;
@ -2603,8 +2587,8 @@ var
Begin
{ save the reg }
reg := actasmpattern;
{ is the syntax of the form: [REG:REG...] }
consume(AS_REGISTER);
{ is the syntax of the form: [REG:REG...] }
if actasmtoken = AS_COLON then
begin
segreg := TRUE;
@ -2614,24 +2598,20 @@ var
instr.operands[operandnum].ref.segment := findsegment(reg);
{ Here we should process the syntax of the form }
{ [reg:reg...] }
{!!!!!!!!!!!!!!!!!!!!!!!! }
end
{ This is probably of the following syntax: }
{ SREG:[REG...] where SReg: is optional. }
{ Therefore we immediately say that reg }
{ is the base. }
else
else { SREG:[REG...] where SReg: is optional. }
Begin
if instr.operands[operandnum].ref.base <> R_NO then
Message(assem_e_defining_base_more_than_once);
instr.operands[operandnum].ref.base := findregister(reg);
end;
{ we process this type of syntax immediately... }
case actasmtoken of
{ REG:[REG].Field.Field ... }
{ REG:[REG].Field[REG].Field... }
AS_RBRACKET: Begin
{ SREG:[REG].Field.Field ... }
{ SREG:[REG].Field[REG].Field... }
AS_RBRACKET:
Begin
Consume(AS_RBRACKET);
{ check for record fields }
if actasmtoken = AS_DOT then
@ -2641,8 +2621,11 @@ var
else
Message(assem_e_syn_reference);
end;
{ REG:[REG +/- ...].Field.Field ... }
AS_PLUS,AS_MINUS: Begin
{ SREG:[REG +/- ...].Field.Field ... }
AS_PLUS,
AS_MINUS:
Begin
if actasmtoken = AS_MINUS then
Begin
expr := '-';
@ -2664,40 +2647,42 @@ var
instr.operands[operandnum].ref.index := findregister(actasmpattern);
Consume(AS_REGISTER);
case actasmtoken of
AS_RBRACKET: { REG:[REG+REG].Field.Field... }
AS_RBRACKET: { SREG:[REG+REG].Field.Field... }
Begin
Consume(AS_RBRACKET);
Case actasmtoken of
AS_DOT: BuildRecordOffset(instr,'');
AS_COMMA,AS_SEPARATOR: exit;
AS_COMMA,
AS_SEPARATOR: exit;
else
Message(assem_e_syntax_error);
end
end;
AS_PLUS,AS_MINUS: { REG:[REG+REG+/-expr... }
end;
AS_PLUS,
AS_MINUS: { REG:[REG+REG+/-expr... }
Begin
if instr.operands[operandnum].ref.offset <> 0 then
Message(assem_f_internal_error_in_buildreference);
instr.operands[operandnum].ref.offset :=
BuildRefExpression;
instr.operands[operandnum].ref.offset:=BuildRefExpression;
case actasmtoken of
AS_DOT: BuildRecordOffset(instr,'');
AS_COMMA,AS_SEPARATOR: ;
AS_COMMA,
AS_SEPARATOR: ;
else
Message(assem_e_syntax_error);
end; { end case }
end;
AS_STAR: Begin { REG:[REG+REG*SCALING...].Field.Field... }
end;
AS_STAR: { REG:[REG+REG*SCALING...].Field.Field... }
begin
BuildScaling(instr);
end;
else
Begin
Message(assem_e_syntax_error);
end;
end; { end case }
end
else if actasmtoken = AS_STAR then
{ REG:[REG*SCALING ... ] }
else
{ REG:[REG*(+/-)SCALING ... ] }
if actasmtoken = AS_STAR then
Begin
BuildScaling(instr);
end
@ -2709,14 +2694,16 @@ var
instr.operands[operandnum].ref.offset := BuildRefExpression;
case actasmtoken of
AS_DOT: BuildRecordOffset(instr,'');
AS_COMMA,AS_SEPARATOR: ;
AS_COMMA,
AS_SEPARATOR: ;
else
Message(assem_e_syntax_error);
end; { end case }
end;
end; { end if }
end; { end this case }
{ REG:[REG*scaling] ... }
AS_STAR: Begin
AS_STAR: { REG:[REG*scaling] ... }
Begin
BuildScaling(instr);
end;
end;
@ -3517,7 +3504,11 @@ begin
end.
{
$Log$
Revision 1.18 1998-12-11 00:03:43 peter
Revision 1.19 1998-12-23 22:55:57 peter
+ rec.field(%esi) support
+ [esi+rec.field] support
Revision 1.18 1998/12/11 00:03:43 peter
+ globtype,tokens,version unit splitted from globals
Revision 1.17 1998/12/08 23:03:46 jonas