summaryrefslogtreecommitdiff
path: root/compiler/x86/rax86.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/x86/rax86.pas')
-rw-r--r--compiler/x86/rax86.pas107
1 files changed, 63 insertions, 44 deletions
diff --git a/compiler/x86/rax86.pas b/compiler/x86/rax86.pas
index 19bddb2fba..c3f4799abc 100644
--- a/compiler/x86/rax86.pas
+++ b/compiler/x86/rax86.pas
@@ -524,21 +524,12 @@ begin
end
else
case MemRefInfo(opcode).MemRefSize of
- msiMultiple8,
msiMem8: memrefsize := 8;
- msiMultiple16,
msiMem16: memrefsize := 16;
- msiMultiple32,
msiMem32: memrefsize := 32;
- //msiXMem64,
- //msiYMem64,
- msiMultiple64,
msiMem64: memrefsize := 64;
- msiMultiple128,
msiMem128: memrefsize := 128;
- msiMultiple256,
msiMem256: memrefsize := 256;
- msiMultiple512,
msiMem512: memrefsize := 512;
msiMemRegx16y32:
begin
@@ -706,8 +697,16 @@ begin
msiYMem64,
msiZMem64: ; // ignore; gather/scatter opcodes haven a fixed element-size, not a fixed memory-size
// the vector-register have indices with base of the memory-address in the memory-operand
+ msiMultipleMinSize8,
+ msiMultipleMinSize16,
+ msiMultipleMinSize32,
+ msiMultipleMinSize64,
+ msiMultipleMinSize128,
+ msiMultipleMinSize256,
+ msiMultipleMinSize512: ; // ignore
msiNoSize,
- msiUnkown,
+ msiNoMemRef,
+ msiUnknown,
msiUnsupported,
msiVMemMultiple,
msiVMemRegSize,
@@ -737,7 +736,25 @@ begin
;
end;
- if memopsize = 0 then memopsize := topsize2memsize[tx86operand(operands[i]).opsize];
+ //if memopsize = 0 then memopsize := topsize2memsize[tx86operand(operands[i]).opsize];
+
+ if memopsize = 0 then
+ begin
+ {$ifdef i386}
+ { 64-bit operands are allowed for SSE and AVX instructions, so
+ go by the byte size instead for these families of opcodes }
+ if (MemRefInfo(opcode).ExistsSSEAVX) then
+ begin
+ memopsize := tx86operand(operands[i]).typesize * 8;
+ if tx86operand(operands[i]).typesize = 8 then
+ { Will be S_L otherwise and won't be corrected in time }
+ tx86operand(operands[i]).opsize := S_Q;
+ end
+ else
+ {$endif i386}
+ memopsize := topsize2memsize[tx86operand(operands[i]).opsize];
+ end;
+
if (memopsize > 0) and
(memrefsize > 0) then
@@ -759,30 +776,32 @@ begin
std_op2str[opcode],
ToStr(memoffset));
end
- else if (memopsize < (memrefsize + memoffset * 8)) then
+ else if ((tx86operand(operands[i]).hastype) and (memopsize < memrefsize)) or
+ (memopsize < (memrefsize + memoffset * 8)) then
begin
- if memoffset = 0 then
+ if memopsize < memrefsize then
begin
- Message3(asmr_w_check_mem_operand_size3,
- std_op2str[opcode],
- ToStr(memopsize),
- ToStr(memrefsize)
- );
- end
- else
- begin
- Message4(asmr_w_check_mem_operand_size_offset,
- std_op2str[opcode],
- ToStr(memopsize),
- ToStr(memrefsize),
- ToStr(memoffset)
- );
+ if memoffset = 0 then
+ begin
+ Message3(asmr_w_check_mem_operand_size3,
+ std_op2str[opcode],
+ ToStr(memopsize),
+ ToStr(memrefsize)
+ );
+ end
+ else
+ begin
+ Message4(asmr_w_check_mem_operand_size_offset,
+ std_op2str[opcode],
+ ToStr(memopsize),
+ ToStr(memrefsize),
+ ToStr(memoffset)
+ );
+ end;
end;
end;
end;
end;
-
-
end;
end;
end;
@@ -821,7 +840,7 @@ begin
tx86operand(operands[i]).opsize := S_B;
tx86operand(operands[i]).size := OS_8;
end;
- msiMultiple8:
+ msiMultipleMinSize8:
begin
tx86operand(operands[i]).opsize := S_B;
tx86operand(operands[i]).size := OS_8;
@@ -833,7 +852,7 @@ begin
tx86operand(operands[i]).opsize := S_W;
tx86operand(operands[i]).size := OS_16;
end;
- msiMultiple16:
+ msiMultipleMinSize16:
begin
tx86operand(operands[i]).opsize := S_W;
tx86operand(operands[i]).size := OS_16;
@@ -845,7 +864,7 @@ begin
tx86operand(operands[i]).opsize := S_L;
tx86operand(operands[i]).size := OS_32;
end;
- msiMultiple32:
+ msiMultipleMinSize32:
begin
tx86operand(operands[i]).opsize := S_L;
tx86operand(operands[i]).size := OS_32;
@@ -857,7 +876,7 @@ begin
tx86operand(operands[i]).opsize := S_Q;
tx86operand(operands[i]).size := OS_M64;
end;
- msiMultiple64:
+ msiMultipleMinSize64:
begin
tx86operand(operands[i]).opsize := S_Q;
tx86operand(operands[i]).size := OS_M64;
@@ -869,7 +888,7 @@ begin
tx86operand(operands[i]).opsize := S_XMM;
tx86operand(operands[i]).size := OS_M128;
end;
- msiMultiple128:
+ msiMultipleMinSize128:
begin
tx86operand(operands[i]).opsize := S_XMM;
tx86operand(operands[i]).size := OS_M128;
@@ -882,7 +901,7 @@ begin
tx86operand(operands[i]).size := OS_M256;
opsize := S_YMM;
end;
- msiMultiple256:
+ msiMultipleMinSize256:
begin
tx86operand(operands[i]).opsize := S_YMM;
tx86operand(operands[i]).size := OS_M256;
@@ -896,7 +915,7 @@ begin
tx86operand(operands[i]).size := OS_M512;
opsize := S_ZMM;
end;
- msiMultiple512:
+ msiMultipleMinSize512:
begin
tx86operand(operands[i]).opsize := S_ZMM;
tx86operand(operands[i]).size := OS_M512;
@@ -1182,9 +1201,10 @@ begin
msiZMem64: ; // ignore; gather/scatter opcodes haven a fixed element-size, not a fixed memory-size
// the vector-register have indices with base of the memory-address in the memory-operand
msiNoSize: ; // all memory-sizes are ok
+ msiNoMemRef:; // ignore;
msiVMemMultiple,
msiVMemRegSize: ; // ignore
- msiUnkown,
+ msiUnknown,
msiUnsupported,
msiMultiple: Message(asmr_e_unable_to_determine_reference_size); // TODO individual message
else
@@ -1215,7 +1235,7 @@ begin
internalerror(2019050910);
end;
{$endif}
- csiUnkown, csiMultiple, csiNoSize:
+ csiUnknown, csiMultiple, csiNoSize:
;
end;
else
@@ -1869,14 +1889,13 @@ begin
asize:=OT_BITS32;
OS_64,OS_S64:
begin
- { Only FPU operations know about 64bit values, for all
- integer operations it is seen as 32bit
+ { Only FPU and SSE/AVX operations know about 64bit
+ values, for all integer operations it is seen as 32bit
- this applies only to i386, see tw16622}
+ this applies only to i386, see tw16622}
- if gas_needsuffix[opcode] in [attsufFPU,attsufFPUint] then
- asize:=OT_BITS64
- else if MemRefInfo(opcode).ExistsSSEAVX then asize:=OT_BITS64
+ if (gas_needsuffix[opcode] in [attsufFPU,attsufFPUint]) or (MemRefInfo(opcode).ExistsSSEAVX) then
+ asize:=OT_BITS64
{$ifdef i386}
else
asize:=OT_BITS32