|
@@ -65,7 +65,7 @@ Unit Rax86int;
|
|
procedure BuildRecordOffsetSize(const expr: string;var offset:aint;var size:aint; var mangledname: string; needvmtofs: boolean);
|
|
procedure BuildRecordOffsetSize(const expr: string;var offset:aint;var size:aint; var mangledname: string; needvmtofs: boolean);
|
|
procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype);
|
|
procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;var value:aint;var asmsym:string;var asmsymtyp:TAsmsymtype);
|
|
function BuildConstExpression:aint;
|
|
function BuildConstExpression:aint;
|
|
- function BuildRefConstExpression:aint;
|
|
|
|
|
|
+ function BuildRefConstExpression(startingminus:boolean=false):aint;
|
|
procedure BuildReference(oper : tx86operand);
|
|
procedure BuildReference(oper : tx86operand);
|
|
procedure BuildOperand(oper: tx86operand;istypecast:boolean);
|
|
procedure BuildOperand(oper: tx86operand;istypecast:boolean);
|
|
procedure BuildConstantOperand(oper: tx86operand);
|
|
procedure BuildConstantOperand(oper: tx86operand);
|
|
@@ -1141,13 +1141,13 @@ Unit Rax86int;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
- Function tx86intreader.BuildRefConstExpression:aint;
|
|
|
|
|
|
+ Function tx86intreader.BuildRefConstExpression(startingminus:boolean):aint;
|
|
var
|
|
var
|
|
l : aint;
|
|
l : aint;
|
|
hs : string;
|
|
hs : string;
|
|
hssymtyp : TAsmsymtype;
|
|
hssymtyp : TAsmsymtype;
|
|
begin
|
|
begin
|
|
- BuildConstSymbolExpression(false,true,false,l,hs,hssymtyp);
|
|
|
|
|
|
+ BuildConstSymbolExpression(false,true,startingminus,l,hs,hssymtyp);
|
|
if hs<>'' then
|
|
if hs<>'' then
|
|
Message(asmr_e_relocatable_symbol_not_allowed);
|
|
Message(asmr_e_relocatable_symbol_not_allowed);
|
|
BuildRefConstExpression:=l;
|
|
BuildRefConstExpression:=l;
|
|
@@ -1190,7 +1190,8 @@ Unit Rax86int;
|
|
(SearchIConstant(actasmpattern,l) or
|
|
(SearchIConstant(actasmpattern,l) or
|
|
SearchRecordType(actasmpattern)) then
|
|
SearchRecordType(actasmpattern)) then
|
|
begin
|
|
begin
|
|
- l:=BuildRefConstExpression;
|
|
|
|
|
|
+ l:=BuildRefConstExpression(negative);
|
|
|
|
+ negative:=false; { "l" was negated if necessary }
|
|
GotPlus:=(prevasmtoken=AS_PLUS);
|
|
GotPlus:=(prevasmtoken=AS_PLUS);
|
|
GotStar:=(prevasmtoken=AS_STAR);
|
|
GotStar:=(prevasmtoken=AS_STAR);
|
|
case oper.opr.typ of
|
|
case oper.opr.typ of
|
|
@@ -1198,23 +1199,15 @@ Unit Rax86int;
|
|
begin
|
|
begin
|
|
if GotStar then
|
|
if GotStar then
|
|
Message(asmr_e_invalid_reference_syntax);
|
|
Message(asmr_e_invalid_reference_syntax);
|
|
- if negative then
|
|
|
|
- Dec(oper.opr.localsymofs,l)
|
|
|
|
- else
|
|
|
|
- Inc(oper.opr.localsymofs,l);
|
|
|
|
|
|
+ Inc(oper.opr.localsymofs,l);
|
|
end;
|
|
end;
|
|
OPR_REFERENCE :
|
|
OPR_REFERENCE :
|
|
begin
|
|
begin
|
|
if GotStar then
|
|
if GotStar then
|
|
oper.opr.ref.scalefactor:=l
|
|
oper.opr.ref.scalefactor:=l
|
|
else
|
|
else
|
|
- begin
|
|
|
|
- if negative then
|
|
|
|
- Dec(oper.opr.ref.offset,l)
|
|
|
|
- else
|
|
|
|
- Inc(oper.opr.ref.offset,l);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
|
|
+ Inc(oper.opr.ref.offset,l);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
@@ -1427,6 +1420,11 @@ Unit Rax86int;
|
|
begin
|
|
begin
|
|
if (oper.opr.localindexreg<>NR_NO) then
|
|
if (oper.opr.localindexreg<>NR_NO) then
|
|
Message(asmr_e_multiple_index);
|
|
Message(asmr_e_multiple_index);
|
|
|
|
+{$ifdef x86_64}
|
|
|
|
+ { Locals/parameters cannot be accessed RIP-relative. Need a dedicated error message here? }
|
|
|
|
+ if (hreg=NR_RIP) then
|
|
|
|
+ Message(asmr_e_no_local_or_para_allowed);
|
|
|
|
+{$endif x86_64}
|
|
oper.opr.localindexreg:=hreg;
|
|
oper.opr.localindexreg:=hreg;
|
|
if scale<>0 then
|
|
if scale<>0 then
|
|
begin
|
|
begin
|
|
@@ -1981,6 +1979,7 @@ Unit Rax86int;
|
|
t: TRegister;
|
|
t: TRegister;
|
|
is_far_const:boolean;
|
|
is_far_const:boolean;
|
|
i:byte;
|
|
i:byte;
|
|
|
|
+ tmp: toperand;
|
|
begin
|
|
begin
|
|
PrefixOp:=A_None;
|
|
PrefixOp:=A_None;
|
|
OverrideOp:=A_None;
|
|
OverrideOp:=A_None;
|
|
@@ -1990,7 +1989,6 @@ Unit Rax86int;
|
|
if is_prefix(actopcode) then
|
|
if is_prefix(actopcode) then
|
|
with instr do
|
|
with instr do
|
|
begin
|
|
begin
|
|
- OpOrder:=op_intel;
|
|
|
|
PrefixOp:=ActOpcode;
|
|
PrefixOp:=ActOpcode;
|
|
opcode:=ActOpcode;
|
|
opcode:=ActOpcode;
|
|
condition:=ActCondition;
|
|
condition:=ActCondition;
|
|
@@ -2002,7 +2000,6 @@ Unit Rax86int;
|
|
if is_override(actopcode) then
|
|
if is_override(actopcode) then
|
|
with instr do
|
|
with instr do
|
|
begin
|
|
begin
|
|
- OpOrder:=op_intel;
|
|
|
|
OverrideOp:=ActOpcode;
|
|
OverrideOp:=ActOpcode;
|
|
opcode:=ActOpcode;
|
|
opcode:=ActOpcode;
|
|
condition:=ActCondition;
|
|
condition:=ActCondition;
|
|
@@ -2026,7 +2023,6 @@ Unit Rax86int;
|
|
{ Fill the instr object with the current state }
|
|
{ Fill the instr object with the current state }
|
|
with instr do
|
|
with instr do
|
|
begin
|
|
begin
|
|
- OpOrder:=op_intel;
|
|
|
|
Opcode:=ActOpcode;
|
|
Opcode:=ActOpcode;
|
|
condition:=ActCondition;
|
|
condition:=ActCondition;
|
|
opsize:=ActOpsize;
|
|
opsize:=ActOpsize;
|
|
@@ -2053,15 +2049,13 @@ Unit Rax86int;
|
|
{$endif x86_64}
|
|
{$endif x86_64}
|
|
;
|
|
;
|
|
{ We are reading operands, so opcode will be an AS_ID }
|
|
{ We are reading operands, so opcode will be an AS_ID }
|
|
- operandnum:=1;
|
|
|
|
|
|
+ { process operands backwards to get them in AT&T order }
|
|
|
|
+ operandnum:=max_operands;
|
|
is_far_const:=false;
|
|
is_far_const:=false;
|
|
Consume(AS_OPCODE);
|
|
Consume(AS_OPCODE);
|
|
{ Zero operand opcode ? }
|
|
{ Zero operand opcode ? }
|
|
if actasmtoken in [AS_SEPARATOR,AS_END] then
|
|
if actasmtoken in [AS_SEPARATOR,AS_END] then
|
|
- begin
|
|
|
|
- operandnum:=0;
|
|
|
|
- exit;
|
|
|
|
- end;
|
|
|
|
|
|
+ exit;
|
|
{ Read Operands }
|
|
{ Read Operands }
|
|
repeat
|
|
repeat
|
|
case actasmtoken of
|
|
case actasmtoken of
|
|
@@ -2073,10 +2067,13 @@ Unit Rax86int;
|
|
{ Operand delimiter }
|
|
{ Operand delimiter }
|
|
AS_COMMA :
|
|
AS_COMMA :
|
|
begin
|
|
begin
|
|
- if operandnum > Max_Operands then
|
|
|
|
|
|
+ { should have something before the comma }
|
|
|
|
+ if instr.operands[operandnum].opr.typ=OPR_NONE then
|
|
|
|
+ Message(asmr_e_syntax_error);
|
|
|
|
+ if operandnum <= 1 then
|
|
Message(asmr_e_too_many_operands)
|
|
Message(asmr_e_too_many_operands)
|
|
else
|
|
else
|
|
- Inc(operandnum);
|
|
|
|
|
|
+ Dec(operandnum);
|
|
Consume(AS_COMMA);
|
|
Consume(AS_COMMA);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2084,10 +2081,10 @@ Unit Rax86int;
|
|
AS_COLON:
|
|
AS_COLON:
|
|
begin
|
|
begin
|
|
is_far_const:=true;
|
|
is_far_const:=true;
|
|
- if operandnum>1 then
|
|
|
|
|
|
+ if operandnum<max_operands then
|
|
message(asmr_e_too_many_operands)
|
|
message(asmr_e_too_many_operands)
|
|
else
|
|
else
|
|
- inc(operandnum);
|
|
|
|
|
|
+ dec(operandnum);
|
|
consume(AS_COLON);
|
|
consume(AS_COLON);
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -2117,6 +2114,15 @@ Unit Rax86int;
|
|
BuildOperand(instr.Operands[operandnum] as tx86operand,false);
|
|
BuildOperand(instr.Operands[operandnum] as tx86operand,false);
|
|
end; { end case }
|
|
end; { end case }
|
|
until false;
|
|
until false;
|
|
|
|
+
|
|
|
|
+ { shift operands to start from 1, exchange to make sure they are destroyed correctly }
|
|
|
|
+ for i:=operandnum to max_operands do
|
|
|
|
+ begin
|
|
|
|
+ tmp:=instr.operands[i+1-operandnum];
|
|
|
|
+ instr.operands[i+1-operandnum]:=instr.operands[i];
|
|
|
|
+ instr.operands[i]:=tmp;
|
|
|
|
+ end;
|
|
|
|
+ operandnum:=(max_operands+1)-operandnum;
|
|
instr.ops:=operandnum;
|
|
instr.ops:=operandnum;
|
|
{ Check operands }
|
|
{ Check operands }
|
|
for i:=1 to operandnum do
|
|
for i:=1 to operandnum do
|
|
@@ -2335,9 +2341,6 @@ Unit Rax86int;
|
|
BuildOpcode(instr);
|
|
BuildOpcode(instr);
|
|
with instr do
|
|
with instr do
|
|
begin
|
|
begin
|
|
- { We need AT&T style operands }
|
|
|
|
- Swapoperands;
|
|
|
|
- { Must be done with args in ATT order }
|
|
|
|
CheckNonCommutativeOpcodes;
|
|
CheckNonCommutativeOpcodes;
|
|
AddReferenceSizes;
|
|
AddReferenceSizes;
|
|
SetInstructionOpsize;
|
|
SetInstructionOpsize;
|