From ecc3ce64eaeeca34fbcdf297fdea90420845fb11 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 16 Jan 2021 22:46:25 +0000 Subject: [PATCH] * x86: some fixes to enable 8 and 16 bit operations git-svn-id: trunk@48166 - --- compiler/x86/cgx86.pas | 13 ++++++++++++- compiler/x86/nx86mat.pas | 5 ++++- compiler/x86_64/nx64mat.pas | 3 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index b270ddd59d..5ade18a90c 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -1995,7 +1995,7 @@ unit cgx86; href.scalefactor:=a; list.concat(taicpu.op_ref_reg(A_LEA,TCgSize2OpSize[size],href,dst)); end - else if (op in [OP_MUL,OP_IMUL]) and (size in [OS_32,OS_S32,OS_64,OS_S64]) and + else if (op in [OP_MUL,OP_IMUL]) and (size in [OS_16,OS_S16,OS_32,OS_S32,OS_64,OS_S64]) and (a>1) and (a<=maxLongint) and not ispowerof2(int64(a),power) then begin { MUL with overflow checking should be handled specifically in the code generator } @@ -2343,6 +2343,17 @@ unit cgx86; begin if reg2opsize(src) <> dstsize then internalerror(200109226); + { x86 does not have an 8 Bit imul, so do 16 Bit multiplication + we do not need to zero/sign extend as we discard the upper bits anyways } + if (TOpCG2AsmOp[op]=A_IMUL) and (size in [OS_8,OS_S8]) then + begin + { this might only happen if no overflow checking is done } + if cs_check_overflow in current_settings.localswitches then + Internalerror(2021011601); + src:=makeregsize(list,src,OS_16); + dst:=makeregsize(list,dst,OS_16); + dstsize:=S_W; + end; instr:=taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,src,dst); list.concat(instr); end; diff --git a/compiler/x86/nx86mat.pas b/compiler/x86/nx86mat.pas index 036fb2dc67..23a43cd209 100644 --- a/compiler/x86/nx86mat.pas +++ b/compiler/x86/nx86mat.pas @@ -387,7 +387,10 @@ interface cgsize:=def_cgsize(resultdef); opsize:=TCGSize2OpSize[cgsize]; rega:=newreg(R_INTREGISTER,RS_EAX,cgsize2subreg(R_INTREGISTER,cgsize)); - regd:=newreg(R_INTREGISTER,RS_EDX,cgsize2subreg(R_INTREGISTER,cgsize)); + if cgsize in [OS_8,OS_S8] then + regd:=NR_AH + else + regd:=newreg(R_INTREGISTER,RS_EDX,cgsize2subreg(R_INTREGISTER,cgsize)); location_reset(location,LOC_REGISTER,cgsize); hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,false); diff --git a/compiler/x86_64/nx64mat.pas b/compiler/x86_64/nx64mat.pas index 14ce93c21f..74731bccac 100644 --- a/compiler/x86_64/nx64mat.pas +++ b/compiler/x86_64/nx64mat.pas @@ -43,6 +43,7 @@ implementation uses globtype,constexp, + cutils, aasmdata,defutil, pass_2, ncon, @@ -70,7 +71,7 @@ implementation op:=OP_SHR; opsize:=def_cgsize(resultdef); - mask:=resultdef.size*8-1; + mask:=max(resultdef.size,4)*8-1; { load left operators in a register } if not(left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) or