* make fpu/mmx/xmm/ymm registers numbers instead of flags to have enough space for zmm/bnd/k registers

git-svn-id: trunk@38116 -
This commit is contained in:
florian 2018-02-04 20:29:41 +00:00
parent 2d52536460
commit e6a6938787

View File

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