summaryrefslogtreecommitdiff
path: root/compiler/x86/cgx86.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/x86/cgx86.pas')
-rw-r--r--compiler/x86/cgx86.pas71
1 files changed, 53 insertions, 18 deletions
diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas
index 5d02763c28..3208139830 100644
--- a/compiler/x86/cgx86.pas
+++ b/compiler/x86/cgx86.pas
@@ -132,19 +132,25 @@ unit cgx86;
end;
const
-{$ifdef x86_64}
+{$if defined(x86_64)}
TCGSize2OpSize: Array[tcgsize] of topsize =
(S_NO,S_B,S_W,S_L,S_Q,S_XMM,S_B,S_W,S_L,S_Q,S_XMM,
S_FS,S_FL,S_FX,S_IQ,S_FXX,
S_NO,S_NO,S_NO,S_MD,S_XMM,S_YMM,
S_NO,S_NO,S_NO,S_NO,S_XMM,S_YMM);
-{$else x86_64}
+{$elseif defined(i386)}
TCGSize2OpSize: Array[tcgsize] of topsize =
(S_NO,S_B,S_W,S_L,S_L,S_T,S_B,S_W,S_L,S_L,S_L,
S_FS,S_FL,S_FX,S_IQ,S_FXX,
S_NO,S_NO,S_NO,S_MD,S_XMM,S_YMM,
S_NO,S_NO,S_NO,S_NO,S_XMM,S_YMM);
-{$endif x86_64}
+{$elseif defined(i8086)}
+ TCGSize2OpSize: Array[tcgsize] of topsize =
+ (S_NO,S_B,S_W,S_W,S_W,S_T,S_B,S_W,S_W,S_W,S_W,
+ S_FS,S_FL,S_FX,S_IQ,S_FXX,
+ S_NO,S_NO,S_NO,S_MD,S_XMM,S_YMM,
+ S_NO,S_NO,S_NO,S_NO,S_XMM,S_YMM);
+{$endif}
{$ifndef NOTARGETWIN}
winstackpagesize = 4096;
@@ -369,7 +375,7 @@ unit cgx86;
if (ref.refaddr in [addr_pic,addr_pic_no_got]) then
exit;
-{$ifdef x86_64}
+{$if defined(x86_64)}
{ Only 32bit is allowed }
{ Note that this isn't entirely correct: for RIP-relative targets/memory models,
it is actually (offset+@symbol-RIP) that should fit into 32 bits. Since two last
@@ -505,7 +511,7 @@ unit cgx86;
end;
end;
-{$else x86_64}
+{$elseif defined(i386)}
add_hreg:=false;
if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) then
begin
@@ -561,7 +567,17 @@ unit cgx86;
ref.base:=hreg;
end;
end;
-{$endif x86_64}
+{$elseif defined(i8086)}
+ { i8086 does not support stack relative addressing }
+ if ref.base = NR_STACK_POINTER_REG then
+ begin
+ href:=ref;
+ href.base:=getaddressregister(list);
+ { let the register allocator find a suitable register for the reference }
+ list.Concat(Taicpu.op_reg_reg(A_MOV, S_W, NR_SP, href.base));
+ ref:=href;
+ end
+{$endif}
end;
@@ -1538,6 +1554,14 @@ unit cgx86;
procedure tcgx86.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
+ const
+{$if defined(cpu64bitalu) or defined(cpu32bitalu)}
+ REGCX=NR_ECX;
+ REGCX_Size = OS_32;
+{$elseif defined(cpu16bitalu)}
+ REGCX=NR_CX;
+ REGCX_Size = OS_16;
+{$endif}
var
dstsize: topsize;
instr:Taicpu;
@@ -1559,10 +1583,10 @@ unit cgx86;
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
begin
{ Use ecx to load the value, that allows better coalescing }
- getcpuregister(list,NR_ECX);
- a_load_reg_reg(list,size,OS_32,src,NR_ECX);
+ getcpuregister(list,REGCX);
+ a_load_reg_reg(list,size,REGCX_Size,src,REGCX);
list.concat(taicpu.op_reg_reg(Topcg2asmop[op],tcgsize2opsize[size],NR_CL,dst));
- ungetcpuregister(list,NR_ECX);
+ ungetcpuregister(list,REGCX);
end;
else
begin
@@ -1805,15 +1829,22 @@ unit cgx86;
procedure Tcgx86.g_concatcopy(list:TAsmList;const source,dest:Treference;len:tcgint);
const
-{$ifdef cpu64bitalu}
+{$if defined(cpu64bitalu)}
REGCX=NR_RCX;
REGSI=NR_RSI;
REGDI=NR_RDI;
-{$else cpu64bitalu}
+ copy_len_sizes = [1, 2, 4, 8];
+{$elseif defined(cpu32bitalu)}
REGCX=NR_ECX;
REGSI=NR_ESI;
REGDI=NR_EDI;
-{$endif cpu64bitalu}
+ copy_len_sizes = [1, 2, 4];
+{$elseif defined(cpu16bitalu)}
+ REGCX=NR_CX;
+ REGSI=NR_SI;
+ REGDI=NR_DI;
+ copy_len_sizes = [1, 2];
+{$endif}
type copymode=(copy_move,copy_mmx,copy_string);
@@ -1837,7 +1868,7 @@ unit cgx86;
cm:=copy_string;
if (cs_opt_size in current_settings.optimizerswitches) and
not((len<=16) and (cm=copy_mmx)) and
- not(len in [1,2,4{$ifdef x86_64},8{$endif x86_64}]) then
+ not(len in copy_len_sizes) then
cm:=copy_string;
if (source.segment<>NR_NO) or
(dest.segment<>NR_NO) then
@@ -1861,11 +1892,13 @@ unit cgx86;
copysize:=2;
cgsize:=OS_16;
end
+{$if defined(cpu32bitalu) or defined(cpu64bitalu)}
else if len<8 then
begin
copysize:=4;
cgsize:=OS_32;
end
+{$endif cpu32bitalu or cpu64bitalu}
{$ifdef cpu64bitalu}
else if len<16 then
begin
@@ -1951,9 +1984,9 @@ unit cgx86;
end;
getcpuregister(list,REGCX);
-{$ifdef i386}
+{$if defined(i8086) or defined(i386)}
list.concat(Taicpu.op_none(A_CLD,S_NO));
-{$endif i386}
+{$endif i8086 or i386}
if (cs_opt_size in current_settings.optimizerswitches) and
(len>sizeof(aint)+(sizeof(aint) div 2)) then
begin
@@ -1972,11 +2005,13 @@ unit cgx86;
end;
if helpsize>0 then
begin
-{$ifdef cpu64bitalu}
+{$if defined(cpu64bitalu)}
list.concat(Taicpu.op_none(A_MOVSQ,S_NO))
-{$else}
+{$elseif defined(cpu32bitalu)}
list.concat(Taicpu.op_none(A_MOVSD,S_NO));
-{$endif cpu64bitalu}
+{$elseif defined(cpu16bitalu)}
+ list.concat(Taicpu.op_none(A_MOVSW,S_NO));
+{$endif}
end;
if len>=4 then
begin