|
@@ -86,6 +86,8 @@ interface
|
|
|
otf_reg_mmx = $02000000;
|
|
|
otf_reg_xmm = $04000000;
|
|
|
otf_reg_ymm = $08000000;
|
|
|
+
|
|
|
+ otf_reg_extra_mask = $0F000000;
|
|
|
{ Bits 16..19: subclasses, meaning depends on classes field }
|
|
|
otf_sub0 = $00010000;
|
|
|
otf_sub1 = $00020000;
|
|
@@ -93,7 +95,9 @@ interface
|
|
|
otf_sub3 = $00080000;
|
|
|
OT_REG_SMASK = otf_sub0 or otf_sub1 or otf_sub2 or otf_sub3;
|
|
|
|
|
|
- OT_REG_TYPMASK = otf_reg_cdt or otf_reg_gpr or otf_reg_sreg or otf_reg_fpu or otf_reg_mmx or otf_reg_xmm or otf_reg_ymm;
|
|
|
+ OT_REG_EXTRA_MASK = $0F000000;
|
|
|
+
|
|
|
+ OT_REG_TYPMASK = otf_reg_cdt or otf_reg_gpr or otf_reg_sreg or otf_reg_extra_mask;
|
|
|
{ register class 0: CRx, DRx and TRx }
|
|
|
{$ifdef x86_64}
|
|
|
OT_REG_CDT = OT_REGISTER or otf_reg_cdt or OT_BITS64;
|
|
@@ -175,7 +179,7 @@ interface
|
|
|
{ simple [address] offset }
|
|
|
|
|
|
{ Matches any type of r/m operand }
|
|
|
- OT_MEMORY_ANY = OT_MEMORY or OT_RM_GPR or OT_XMMRM or OT_MMXRM or OT_YMMRM;
|
|
|
+ OT_MEMORY_ANY = OT_MEMORY or OT_RM_GPR or OT_XMMRM or OT_MMXRM or OT_YMMRM or OT_REG_EXTRA_MASK;
|
|
|
|
|
|
{ Immediate operands }
|
|
|
OT_IMM8 = OT_IMMEDIATE or OT_BITS8;
|
|
@@ -1096,16 +1100,16 @@ implementation
|
|
|
s:=s+',';
|
|
|
{ type }
|
|
|
addsize:=false;
|
|
|
- if (ot and OT_XMMREG)=OT_XMMREG then
|
|
|
+ if (ot and OT_REG_EXTRA_MASK)=OT_XMMREG then
|
|
|
s:=s+'xmmreg'
|
|
|
else
|
|
|
- if (ot and OT_YMMREG)=OT_YMMREG then
|
|
|
+ if (ot and OT_REG_EXTRA_MASK)=OT_YMMREG then
|
|
|
s:=s+'ymmreg'
|
|
|
else
|
|
|
- if (ot and OT_MMXREG)=OT_MMXREG then
|
|
|
+ if (ot and OT_REG_EXTRA_MASK)=OT_MMXREG then
|
|
|
s:=s+'mmxreg'
|
|
|
else
|
|
|
- if (ot and OT_FPUREG)=OT_FPUREG then
|
|
|
+ if (ot and OT_REG_EXTRA_MASK)=OT_FPUREG then
|
|
|
s:=s+'fpureg'
|
|
|
else
|
|
|
if (ot and OT_REGISTER)=OT_REGISTER then
|
|
@@ -1595,12 +1599,12 @@ implementation
|
|
|
for i:=0 to p^.ops-1 do
|
|
|
begin
|
|
|
insot:=p^.optypes[i];
|
|
|
- if ((insot and OT_XMMRM) = OT_XMMRM) OR
|
|
|
- ((insot and OT_YMMRM) = OT_YMMRM) then
|
|
|
+ if ((insot and (OT_XMMRM or OT_REG_EXTRA_MASK)) = OT_XMMRM) OR
|
|
|
+ ((insot and (OT_YMMRM or OT_REG_EXTRA_MASK)) = OT_YMMRM) then
|
|
|
begin
|
|
|
if (insot and OT_SIZE_MASK) = 0 then
|
|
|
begin
|
|
|
- case insot and (OT_XMMRM or OT_YMMRM) of
|
|
|
+ case insot and (OT_XMMRM or OT_YMMRM or OT_REG_EXTRA_MASK) of
|
|
|
OT_XMMRM: insot := insot or OT_BITS128;
|
|
|
OT_YMMRM: insot := insot or OT_BITS256;
|
|
|
end;
|
|
@@ -3066,14 +3070,14 @@ implementation
|
|
|
end
|
|
|
else if IF_NEC in insentry^.flags then
|
|
|
begin
|
|
|
- { the NEC V20/V30 extensions are incompatible with 386+, due to overlapping opcodes }
|
|
|
+ { the NEC V20/V30 extensions are incompatible with 386+, due to overlapping opcodes }
|
|
|
if objdata.CPUType>=cpu_386 then
|
|
|
Message(asmw_e_instruction_not_supported_by_cpu);
|
|
|
end
|
|
|
else if IF_SANDYBRIDGE in insentry^.flags then
|
|
|
begin
|
|
|
- { todo: handle these properly }
|
|
|
- end;
|
|
|
+ { todo: handle these properly }
|
|
|
+ end;
|
|
|
end;
|
|
|
{$endif i8086}
|
|
|
|
|
@@ -3547,7 +3551,8 @@ implementation
|
|
|
if needed_VEX and
|
|
|
(ops=4) and
|
|
|
(oper[opidx]^.typ=top_reg) and
|
|
|
- (oper[opidx]^.ot and (otf_reg_xmm or otf_reg_ymm)<>0) then
|
|
|
+ ((oper[opidx]^.ot and OT_REG_EXTRA_MASK)=otf_reg_xmm) or
|
|
|
+ ((oper[opidx]^.ot and OT_REG_EXTRA_MASK)=otf_reg_ymm) then
|
|
|
begin
|
|
|
bytes[0] := ((getsupreg(oper[opidx]^.reg) and 15) shl 4);
|
|
|
objdata.writebytes(bytes,1);
|
|
@@ -3725,33 +3730,33 @@ implementation
|
|
|
fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read));
|
|
|
for opcode:=low(tasmop) to high(tasmop) do
|
|
|
with InsProp[opcode] do
|
|
|
- begin
|
|
|
+ begin
|
|
|
if Ch_Rop1 in Ch then
|
|
|
- operation_type_table^[opcode,0]:=operand_read;
|
|
|
+ operation_type_table^[opcode,0]:=operand_read;
|
|
|
if Ch_Wop1 in Ch then
|
|
|
- operation_type_table^[opcode,0]:=operand_write;
|
|
|
+ operation_type_table^[opcode,0]:=operand_write;
|
|
|
if [Ch_RWop1,Ch_Mop1]*Ch<>[] then
|
|
|
- operation_type_table^[opcode,0]:=operand_readwrite;
|
|
|
+ operation_type_table^[opcode,0]:=operand_readwrite;
|
|
|
if Ch_Rop2 in Ch then
|
|
|
- operation_type_table^[opcode,1]:=operand_read;
|
|
|
+ operation_type_table^[opcode,1]:=operand_read;
|
|
|
if Ch_Wop2 in Ch then
|
|
|
- operation_type_table^[opcode,1]:=operand_write;
|
|
|
+ operation_type_table^[opcode,1]:=operand_write;
|
|
|
if [Ch_RWop2,Ch_Mop2]*Ch<>[] then
|
|
|
- operation_type_table^[opcode,1]:=operand_readwrite;
|
|
|
+ operation_type_table^[opcode,1]:=operand_readwrite;
|
|
|
if Ch_Rop3 in Ch then
|
|
|
- operation_type_table^[opcode,2]:=operand_read;
|
|
|
+ operation_type_table^[opcode,2]:=operand_read;
|
|
|
if Ch_Wop3 in Ch then
|
|
|
- operation_type_table^[opcode,2]:=operand_write;
|
|
|
+ operation_type_table^[opcode,2]:=operand_write;
|
|
|
if [Ch_RWop3,Ch_Mop3]*Ch<>[] then
|
|
|
- operation_type_table^[opcode,2]:=operand_readwrite;
|
|
|
+ operation_type_table^[opcode,2]:=operand_readwrite;
|
|
|
if Ch_Rop4 in Ch then
|
|
|
operation_type_table^[opcode,3]:=operand_read;
|
|
|
if Ch_Wop4 in Ch then
|
|
|
operation_type_table^[opcode,3]:=operand_write;
|
|
|
if [Ch_RWop4,Ch_Mop4]*Ch<>[] then
|
|
|
operation_type_table^[opcode,3]:=operand_readwrite;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
|
|
|
|
|
|
function taicpu.spilling_get_operation_type(opnr: longint): topertype;
|
|
@@ -4056,7 +4061,7 @@ implementation
|
|
|
NewRegSize := (insentry^.optypes[j] and OT_SIZE_MASK);
|
|
|
if NewRegSize = 0 then
|
|
|
begin
|
|
|
- case insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG) of
|
|
|
+ case insentry^.optypes[j] and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK) of
|
|
|
OT_MMXREG: begin
|
|
|
NewRegSize := OT_BITS64;
|
|
|
end;
|
|
@@ -4073,7 +4078,7 @@ implementation
|
|
|
end;
|
|
|
|
|
|
actRegSize := actRegSize or NewRegSize;
|
|
|
- actRegTypes := actRegTypes or (insentry^.optypes[j] and (OT_MMXREG OR OT_XMMREG OR OT_YMMREG));
|
|
|
+ actRegTypes := actRegTypes or (insentry^.optypes[j] and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK));
|
|
|
end
|
|
|
else if ((insentry^.optypes[j] and OT_MEMORY) <> 0) then
|
|
|
begin
|
|
@@ -4168,71 +4173,71 @@ implementation
|
|
|
begin
|
|
|
if (actMemCount=2) and ((AsmOp=A_MOVS) or (AsmOp=A_CMPS)) then
|
|
|
actMemCount:=1;
|
|
|
- case actMemCount of
|
|
|
- 0: ; // nothing todo
|
|
|
- 1: begin
|
|
|
- MRefInfo := msiUnkown;
|
|
|
- case actRegMemTypes and (OT_MMXRM OR OT_XMMRM OR OT_YMMRM) of
|
|
|
- OT_MMXRM: actMemSize := actMemSize or OT_BITS64;
|
|
|
- OT_XMMRM: actMemSize := actMemSize or OT_BITS128;
|
|
|
- OT_YMMRM: actMemSize := actMemSize or OT_BITS256;
|
|
|
- end;
|
|
|
-
|
|
|
- case actMemSize of
|
|
|
- 0: MRefInfo := msiNoSize;
|
|
|
- OT_BITS8: MRefInfo := msiMem8;
|
|
|
- OT_BITS16: MRefInfo := msiMem16;
|
|
|
- OT_BITS32: MRefInfo := msiMem32;
|
|
|
- OT_BITS64: MRefInfo := msiMem64;
|
|
|
- OT_BITS128: MRefInfo := msiMem128;
|
|
|
- OT_BITS256: MRefInfo := msiMem256;
|
|
|
- OT_BITS80,
|
|
|
- OT_FAR,
|
|
|
- OT_NEAR,
|
|
|
- OT_SHORT: ; // ignore
|
|
|
- else
|
|
|
- begin
|
|
|
- bitcount := bitcnt(actMemSize);
|
|
|
+ case actMemCount of
|
|
|
+ 0: ; // nothing todo
|
|
|
+ 1: begin
|
|
|
+ MRefInfo := msiUnkown;
|
|
|
+ case actRegMemTypes and (OT_MMXRM or OT_XMMRM or OT_YMMRM or OT_REG_EXTRA_MASK) of
|
|
|
+ OT_MMXRM: actMemSize := actMemSize or OT_BITS64;
|
|
|
+ OT_XMMRM: actMemSize := actMemSize or OT_BITS128;
|
|
|
+ OT_YMMRM: actMemSize := actMemSize or OT_BITS256;
|
|
|
+ end;
|
|
|
|
|
|
- if bitcount > 1 then MRefInfo := msiMultiple
|
|
|
- else InternalError(777203);
|
|
|
- end;
|
|
|
+ case actMemSize of
|
|
|
+ 0: MRefInfo := msiNoSize;
|
|
|
+ OT_BITS8: MRefInfo := msiMem8;
|
|
|
+ OT_BITS16: MRefInfo := msiMem16;
|
|
|
+ OT_BITS32: MRefInfo := msiMem32;
|
|
|
+ OT_BITS64: MRefInfo := msiMem64;
|
|
|
+ OT_BITS128: MRefInfo := msiMem128;
|
|
|
+ OT_BITS256: MRefInfo := msiMem256;
|
|
|
+ OT_BITS80,
|
|
|
+ OT_FAR,
|
|
|
+ OT_NEAR,
|
|
|
+ OT_SHORT: ; // ignore
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ bitcount := bitcnt(actMemSize);
|
|
|
+
|
|
|
+ if bitcount > 1 then MRefInfo := msiMultiple
|
|
|
+ else InternalError(777203);
|
|
|
end;
|
|
|
+ end;
|
|
|
|
|
|
- if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiUnkown then
|
|
|
- begin
|
|
|
- InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := MRefInfo;
|
|
|
- end
|
|
|
- else if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize <> MRefInfo then
|
|
|
- begin
|
|
|
- with InsTabMemRefSizeInfoCache^[AsmOp] do
|
|
|
- begin
|
|
|
- if ((MemRefSize = msiMem8) OR (MRefInfo = msiMem8)) then MemRefSize := msiMultiple8
|
|
|
- else if ((MemRefSize = msiMem16) OR (MRefInfo = msiMem16)) then MemRefSize := msiMultiple16
|
|
|
- else if ((MemRefSize = msiMem32) OR (MRefInfo = msiMem32)) then MemRefSize := msiMultiple32
|
|
|
- else if ((MemRefSize = msiMem64) OR (MRefInfo = msiMem64)) then MemRefSize := msiMultiple64
|
|
|
- else if ((MemRefSize = msiMem128) OR (MRefInfo = msiMem128)) then MemRefSize := msiMultiple128
|
|
|
- else if ((MemRefSize = msiMem256) OR (MRefInfo = msiMem256)) then MemRefSize := msiMultiple256
|
|
|
- else MemRefSize := msiMultiple;
|
|
|
- end;
|
|
|
+ if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize = msiUnkown then
|
|
|
+ begin
|
|
|
+ InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize := MRefInfo;
|
|
|
+ end
|
|
|
+ else if InsTabMemRefSizeInfoCache^[AsmOp].MemRefSize <> MRefInfo then
|
|
|
+ begin
|
|
|
+ with InsTabMemRefSizeInfoCache^[AsmOp] do
|
|
|
+ begin
|
|
|
+ if ((MemRefSize = msiMem8) OR (MRefInfo = msiMem8)) then MemRefSize := msiMultiple8
|
|
|
+ else if ((MemRefSize = msiMem16) OR (MRefInfo = msiMem16)) then MemRefSize := msiMultiple16
|
|
|
+ else if ((MemRefSize = msiMem32) OR (MRefInfo = msiMem32)) then MemRefSize := msiMultiple32
|
|
|
+ else if ((MemRefSize = msiMem64) OR (MRefInfo = msiMem64)) then MemRefSize := msiMultiple64
|
|
|
+ else if ((MemRefSize = msiMem128) OR (MRefInfo = msiMem128)) then MemRefSize := msiMultiple128
|
|
|
+ else if ((MemRefSize = msiMem256) OR (MRefInfo = msiMem256)) then MemRefSize := msiMultiple256
|
|
|
+ else MemRefSize := msiMultiple;
|
|
|
end;
|
|
|
+ end;
|
|
|
|
|
|
- if actRegCount > 0 then
|
|
|
- begin
|
|
|
- case actRegTypes and (OT_MMXREG or OT_XMMREG or OT_YMMREG) of
|
|
|
- OT_MMXREG: RegMMXSizeMask := RegMMXSizeMask or actMemSize;
|
|
|
- OT_XMMREG: RegXMMSizeMask := RegXMMSizeMask or actMemSize;
|
|
|
- OT_YMMREG: RegYMMSizeMask := RegYMMSizeMask or actMemSize;
|
|
|
- else begin
|
|
|
- RegMMXSizeMask := not(0);
|
|
|
- RegXMMSizeMask := not(0);
|
|
|
- RegYMMSizeMask := not(0);
|
|
|
- end;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ if actRegCount > 0 then
|
|
|
+ begin
|
|
|
+ case actRegTypes and (OT_MMXREG or OT_XMMREG or OT_YMMREG or OT_REG_EXTRA_MASK) of
|
|
|
+ OT_MMXREG: RegMMXSizeMask := RegMMXSizeMask or actMemSize;
|
|
|
+ OT_XMMREG: RegXMMSizeMask := RegXMMSizeMask or actMemSize;
|
|
|
+ OT_YMMREG: RegYMMSizeMask := RegYMMSizeMask or actMemSize;
|
|
|
+ else begin
|
|
|
+ RegMMXSizeMask := not(0);
|
|
|
+ RegXMMSizeMask := not(0);
|
|
|
+ RegYMMSizeMask := not(0);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
- else InternalError(777202);
|
|
|
- end;
|
|
|
+ end;
|
|
|
+ else InternalError(777202);
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
inc(insentry);
|