mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-07 20:29:28 +01:00
+ ror/rol functions
+ internal compiler support for ror/rol on i386 git-svn-id: trunk@11466 -
This commit is contained in:
parent
0a26b6a129
commit
1afb1aa9cc
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -7697,6 +7697,7 @@ tests/test/trecreg2.pp svneol=native#text/plain
|
|||||||
tests/test/trecreg3.pp -text
|
tests/test/trecreg3.pp -text
|
||||||
tests/test/trecreg4.pp svneol=native#text/plain
|
tests/test/trecreg4.pp svneol=native#text/plain
|
||||||
tests/test/tresstr.pp svneol=native#text/plain
|
tests/test/tresstr.pp svneol=native#text/plain
|
||||||
|
tests/test/trox1.pp svneol=native#text/plain
|
||||||
tests/test/trstr1.pp svneol=native#text/plain
|
tests/test/trstr1.pp svneol=native#text/plain
|
||||||
tests/test/trstr2.pp svneol=native#text/plain
|
tests/test/trstr2.pp svneol=native#text/plain
|
||||||
tests/test/trstr3.pp svneol=native#text/plain
|
tests/test/trstr3.pp svneol=native#text/plain
|
||||||
|
|||||||
@ -347,7 +347,7 @@ unit cgcpu;
|
|||||||
const
|
const
|
||||||
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
|
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
|
||||||
(A_NONE,A_MOV,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
|
(A_NONE,A_MOV,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
|
||||||
A_NONE,A_NONE,A_NONE,A_SUB,A_EOR);
|
A_NONE,A_NONE,A_NONE,A_SUB,A_EOR,A_NONE,A_NONE);
|
||||||
|
|
||||||
|
|
||||||
procedure tcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
|
procedure tcgarm.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
|
||||||
|
|||||||
@ -102,7 +102,9 @@ interface
|
|||||||
OP_SHL, { logical shift left }
|
OP_SHL, { logical shift left }
|
||||||
OP_SHR, { logical shift right }
|
OP_SHR, { logical shift right }
|
||||||
OP_SUB, { simple subtraction }
|
OP_SUB, { simple subtraction }
|
||||||
OP_XOR { simple exclusive or }
|
OP_XOR, { simple exclusive or }
|
||||||
|
OP_ROL, { rotate left }
|
||||||
|
OP_ROR { rotate right }
|
||||||
);
|
);
|
||||||
|
|
||||||
{# Generic flag values - used for jump locations }
|
{# Generic flag values - used for jump locations }
|
||||||
@ -630,7 +632,7 @@ implementation
|
|||||||
const
|
const
|
||||||
list: array[topcg] of boolean =
|
list: array[topcg] of boolean =
|
||||||
(true,false,true,true,false,false,true,true,false,false,
|
(true,false,true,true,false,false,true,true,false,false,
|
||||||
true,false,false,false,false,true);
|
true,false,false,false,false,true,false,false);
|
||||||
begin
|
begin
|
||||||
commutativeop := list[op];
|
commutativeop := list[op];
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -2465,7 +2465,7 @@ implementation
|
|||||||
if a = 0 then
|
if a = 0 then
|
||||||
op:=OP_NONE;
|
op:=OP_NONE;
|
||||||
end;
|
end;
|
||||||
OP_SAR,OP_SHL,OP_SHR:
|
OP_SAR,OP_SHL,OP_SHR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
if a = 0 then
|
if a = 0 then
|
||||||
op:=OP_NONE;
|
op:=OP_NONE;
|
||||||
|
|||||||
@ -72,6 +72,11 @@ const
|
|||||||
in_writestr_x = 62;
|
in_writestr_x = 62;
|
||||||
in_readstr_x = 63;
|
in_readstr_x = 63;
|
||||||
in_abs_long = 64;
|
in_abs_long = 64;
|
||||||
|
in_ror_x = 65;
|
||||||
|
in_ror_x_x = 66;
|
||||||
|
in_rol_x = 67;
|
||||||
|
in_rol_x_x = 68;
|
||||||
|
|
||||||
|
|
||||||
{ Internal constant functions }
|
{ Internal constant functions }
|
||||||
in_const_sqr = 100;
|
in_const_sqr = 100;
|
||||||
|
|||||||
@ -158,7 +158,9 @@ unit cgcpu;
|
|||||||
A_LSL,
|
A_LSL,
|
||||||
A_LSR,
|
A_LSR,
|
||||||
A_SUB,
|
A_SUB,
|
||||||
A_EOR
|
A_EOR,
|
||||||
|
A_NONE,
|
||||||
|
A_NONE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -54,6 +54,7 @@ interface
|
|||||||
procedure second_round_real; virtual;
|
procedure second_round_real; virtual;
|
||||||
procedure second_trunc_real; virtual;
|
procedure second_trunc_real; virtual;
|
||||||
procedure second_abs_long; virtual;
|
procedure second_abs_long; virtual;
|
||||||
|
procedure second_rox; virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -161,6 +162,11 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{$endif SUPPORT_MMX}
|
{$endif SUPPORT_MMX}
|
||||||
|
in_rol_x,
|
||||||
|
in_rol_x_x,
|
||||||
|
in_ror_x,
|
||||||
|
in_ror_x_x:
|
||||||
|
second_rox;
|
||||||
else internalerror(9);
|
else internalerror(9);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -689,9 +695,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Tcginlinenode.second_get_caller_addr;
|
procedure Tcginlinenode.second_get_caller_addr;
|
||||||
|
var
|
||||||
var frame_ref:Treference;
|
frame_ref:Treference;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||||
begin
|
begin
|
||||||
@ -713,6 +718,65 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcginlinenode.second_rox;
|
||||||
|
var
|
||||||
|
op : topcg;
|
||||||
|
hcountreg : tregister;
|
||||||
|
op1,op2 : tnode;
|
||||||
|
begin
|
||||||
|
{ one or two parameters? }
|
||||||
|
if assigned(tcallparanode(left).right) then
|
||||||
|
begin
|
||||||
|
op1:=tcallparanode(tcallparanode(left).right).left;
|
||||||
|
op2:=tcallparanode(left).left;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
op1:=left;
|
||||||
|
|
||||||
|
secondpass(op1);
|
||||||
|
{ load left operator in a register }
|
||||||
|
location_copy(location,op1.location);
|
||||||
|
case inlinenumber of
|
||||||
|
in_ror_x,
|
||||||
|
in_ror_x_x:
|
||||||
|
op:=OP_ROR;
|
||||||
|
in_rol_x,
|
||||||
|
in_rol_x_x:
|
||||||
|
op:=OP_ROL;
|
||||||
|
end;
|
||||||
|
location_force_reg(current_asmdata.CurrAsmList,location,location.size,false);
|
||||||
|
|
||||||
|
if assigned(tcallparanode(left).right) then
|
||||||
|
begin
|
||||||
|
secondpass(op2);
|
||||||
|
{ rotating by a constant directly coded: }
|
||||||
|
if op2.nodetype=ordconstn then
|
||||||
|
cg.a_op_const_reg(current_asmdata.CurrAsmList,op,location.size,
|
||||||
|
tordconstnode(op2).value.uvalue and (resultdef.size*8-1),location.register)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
location_force_reg(current_asmdata.CurrAsmList,op2.location,location.size,false);
|
||||||
|
{
|
||||||
|
if op2.location.loc<>LOC_REGISTER then
|
||||||
|
begin
|
||||||
|
hcountreg:=cg.getintregister(current_asmdata.CurrAsmList,
|
||||||
|
op2.location.size);
|
||||||
|
cg.a_load_loc_reg(current_asmdata.CurrAsmList,location.size,
|
||||||
|
op2.location,hcountreg);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
hcountreg:=op2.location.register;
|
||||||
|
}
|
||||||
|
{ do modulo 2 operation }
|
||||||
|
cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_AND,op2.location.size,resultdef.size*8-1,op2.location.register);
|
||||||
|
cg.a_op_reg_reg(current_asmdata.CurrAsmList,op,location.size,op2.location.register,location.register);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cg.a_op_const_reg(current_asmdata.CurrAsmList,op,location.size,1,location.register);
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cinlinenode:=tcginlinenode;
|
cinlinenode:=tcginlinenode;
|
||||||
end.
|
end.
|
||||||
|
|||||||
@ -2434,6 +2434,19 @@ implementation
|
|||||||
begin
|
begin
|
||||||
resultdef:=voidpointertype;
|
resultdef:=voidpointertype;
|
||||||
end;
|
end;
|
||||||
|
in_rol_x,
|
||||||
|
in_ror_x:
|
||||||
|
begin
|
||||||
|
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||||
|
resultdef:=left.resultdef;
|
||||||
|
end;
|
||||||
|
in_rol_x_x,
|
||||||
|
in_ror_x_x:
|
||||||
|
begin
|
||||||
|
set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
|
||||||
|
set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
|
||||||
|
resultdef:=tcallparanode(tcallparanode(left).right).left.resultdef;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
internalerror(8);
|
internalerror(8);
|
||||||
end;
|
end;
|
||||||
@ -2781,6 +2794,11 @@ implementation
|
|||||||
expectloc:=tcallparanode(left).left.expectloc;
|
expectloc:=tcallparanode(left).left.expectloc;
|
||||||
end;
|
end;
|
||||||
{$endif SUPPORT_UNALIGNED}
|
{$endif SUPPORT_UNALIGNED}
|
||||||
|
in_rol_x,
|
||||||
|
in_rol_x_x,
|
||||||
|
in_ror_x,
|
||||||
|
in_ror_x_x:
|
||||||
|
expectloc:=LOC_REGISTER;
|
||||||
else
|
else
|
||||||
internalerror(89);
|
internalerror(89);
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -2197,6 +2197,11 @@ begin
|
|||||||
def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
|
def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
{ these cpus have an inline rol/ror implementaion }
|
||||||
|
{$if defined(x86)}
|
||||||
|
def_system_macro('FPC_HAS_INTERNAL_ROX');
|
||||||
|
{$endif}
|
||||||
|
|
||||||
{$ifdef SUPPORT_UNALIGNED}
|
{$ifdef SUPPORT_UNALIGNED}
|
||||||
def_system_macro('FPC_SUPPORTS_UNALIGNED');
|
def_system_macro('FPC_SUPPORTS_UNALIGNED');
|
||||||
def_system_macro('FPC_UNALIGNED_FIXED');
|
def_system_macro('FPC_UNALIGNED_FIXED');
|
||||||
|
|||||||
@ -119,10 +119,10 @@ unit cgcpu;
|
|||||||
const
|
const
|
||||||
TOpCG2AsmOpConstLo: Array[topcg] of TAsmOp = (A_NONE,A_MR,A_ADDI,A_ANDI_,A_DIVWU,
|
TOpCG2AsmOpConstLo: Array[topcg] of TAsmOp = (A_NONE,A_MR,A_ADDI,A_ANDI_,A_DIVWU,
|
||||||
A_DIVW,A_MULLW, A_MULLW, A_NONE,A_NONE,A_ORI,
|
A_DIVW,A_MULLW, A_MULLW, A_NONE,A_NONE,A_ORI,
|
||||||
A_SRAWI,A_SLWI,A_SRWI,A_SUBI,A_XORI);
|
A_SRAWI,A_SLWI,A_SRWI,A_SUBI,A_XORI,A_NONE,A_NONE);
|
||||||
TOpCG2AsmOpConstHi: Array[topcg] of TAsmOp = (A_NONE,A_MR,A_ADDIS,A_ANDIS_,
|
TOpCG2AsmOpConstHi: Array[topcg] of TAsmOp = (A_NONE,A_MR,A_ADDIS,A_ANDIS_,
|
||||||
A_DIVWU,A_DIVW, A_MULLW,A_MULLW,A_NONE,A_NONE,
|
A_DIVWU,A_DIVW, A_MULLW,A_MULLW,A_NONE,A_NONE,
|
||||||
A_ORIS,A_NONE, A_NONE,A_NONE,A_SUBIS,A_XORIS);
|
A_ORIS,A_NONE, A_NONE,A_NONE,A_SUBIS,A_XORIS,A_NONE,A_NONE);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -669,7 +669,7 @@ const
|
|||||||
const
|
const
|
||||||
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
|
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
|
||||||
(A_NONE,A_MR,A_ADD,A_AND,A_DIVWU,A_DIVW,A_MULLW,A_MULLW,A_NEG,A_NOT,A_OR,
|
(A_NONE,A_MR,A_ADD,A_AND,A_DIVWU,A_DIVW,A_MULLW,A_MULLW,A_NEG,A_NOT,A_OR,
|
||||||
A_SRAW,A_SLW,A_SRW,A_SUB,A_XOR);
|
A_SRAW,A_SLW,A_SRW,A_SUB,A_XOR,A_NONE,A_NONE);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (op = OP_MOVE) then
|
if (op = OP_MOVE) then
|
||||||
|
|||||||
@ -1062,10 +1062,10 @@ procedure tcgppc.a_op_reg_reg_reg(list: TAsmList; op: TOpCg;
|
|||||||
const
|
const
|
||||||
op_reg_reg_opcg2asmop32: array[TOpCG] of tasmop =
|
op_reg_reg_opcg2asmop32: array[TOpCG] of tasmop =
|
||||||
(A_NONE, A_MR, A_ADD, A_AND, A_DIVWU, A_DIVW, A_MULLW, A_MULLW, A_NEG, A_NOT, A_OR,
|
(A_NONE, A_MR, A_ADD, A_AND, A_DIVWU, A_DIVW, A_MULLW, A_MULLW, A_NEG, A_NOT, A_OR,
|
||||||
A_SRAW, A_SLW, A_SRW, A_SUB, A_XOR);
|
A_SRAW, A_SLW, A_SRW, A_SUB, A_XOR, A_NONE, A_NONE);
|
||||||
op_reg_reg_opcg2asmop64: array[TOpCG] of tasmop =
|
op_reg_reg_opcg2asmop64: array[TOpCG] of tasmop =
|
||||||
(A_NONE, A_MR, A_ADD, A_AND, A_DIVDU, A_DIVD, A_MULLD, A_MULLD, A_NEG, A_NOT, A_OR,
|
(A_NONE, A_MR, A_ADD, A_AND, A_DIVDU, A_DIVD, A_MULLD, A_MULLD, A_NEG, A_NOT, A_OR,
|
||||||
A_SRAD, A_SLD, A_SRD, A_SUB, A_XOR);
|
A_SRAD, A_SLD, A_SRD, A_SUB, A_XOR, A_NONE, A_NONE);
|
||||||
begin
|
begin
|
||||||
case op of
|
case op of
|
||||||
OP_NEG, OP_NOT:
|
OP_NEG, OP_NOT:
|
||||||
|
|||||||
@ -109,10 +109,10 @@ interface
|
|||||||
|
|
||||||
const
|
const
|
||||||
TOpCG2AsmOp : array[topcg] of TAsmOp=(
|
TOpCG2AsmOp : array[topcg] of TAsmOp=(
|
||||||
A_NONE,A_MOV,A_ADD,A_AND,A_UDIV,A_SDIV,A_SMUL,A_UMUL,A_NEG,A_NOT,A_OR,A_SRA,A_SLL,A_SRL,A_SUB,A_XOR
|
A_NONE,A_MOV,A_ADD,A_AND,A_UDIV,A_SDIV,A_SMUL,A_UMUL,A_NEG,A_NOT,A_OR,A_SRA,A_SLL,A_SRL,A_SUB,A_XOR,A_NONE,A_NONE
|
||||||
);
|
);
|
||||||
TOpCG2AsmOpWithFlags : array[topcg] of TAsmOp=(
|
TOpCG2AsmOpWithFlags : array[topcg] of TAsmOp=(
|
||||||
A_NONE,A_MOV,A_ADDcc,A_ANDcc,A_UDIVcc,A_SDIVcc,A_SMULcc,A_UMULcc,A_NEG,A_NOT,A_ORcc,A_SRA,A_SLL,A_SRL,A_SUBcc,A_XORcc
|
A_NONE,A_MOV,A_ADDcc,A_ANDcc,A_UDIVcc,A_SDIVcc,A_SMULcc,A_UMULcc,A_NEG,A_NOT,A_ORcc,A_SRA,A_SLL,A_SRL,A_SUBcc,A_XORcc,A_NONE,A_NONE
|
||||||
);
|
);
|
||||||
TOpCmp2AsmCond : array[topcmp] of TAsmCond=(C_NONE,
|
TOpCmp2AsmCond : array[topcmp] of TAsmCond=(C_NONE,
|
||||||
C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A
|
C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A
|
||||||
|
|||||||
@ -159,7 +159,7 @@ unit cgx86;
|
|||||||
const
|
const
|
||||||
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_MOV,A_ADD,A_AND,A_DIV,
|
TOpCG2AsmOp: Array[topcg] of TAsmOp = (A_NONE,A_MOV,A_ADD,A_AND,A_DIV,
|
||||||
A_IDIV,A_IMUL,A_MUL,A_NEG,A_NOT,A_OR,
|
A_IDIV,A_IMUL,A_MUL,A_NEG,A_NOT,A_OR,
|
||||||
A_SAR,A_SHL,A_SHR,A_SUB,A_XOR);
|
A_SAR,A_SHL,A_SHR,A_SUB,A_XOR,A_ROL,A_ROR);
|
||||||
|
|
||||||
TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,
|
TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,
|
||||||
C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
|
C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
|
||||||
@ -1098,10 +1098,10 @@ unit cgx86;
|
|||||||
opmm2asmop : array[0..1,OS_F32..OS_F64,topcg] of tasmop = (
|
opmm2asmop : array[0..1,OS_F32..OS_F64,topcg] of tasmop = (
|
||||||
( { scalar }
|
( { scalar }
|
||||||
( { OS_F32 }
|
( { OS_F32 }
|
||||||
A_NOP,A_NOP,A_ADDSS,A_NOP,A_DIVSS,A_NOP,A_NOP,A_MULSS,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBSS,A_NOP
|
A_NOP,A_NOP,A_ADDSS,A_NOP,A_DIVSS,A_NOP,A_NOP,A_MULSS,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBSS,A_NOP,A_NOP,A_NOP
|
||||||
),
|
),
|
||||||
( { OS_F64 }
|
( { OS_F64 }
|
||||||
A_NOP,A_NOP,A_ADDSD,A_NOP,A_DIVSD,A_NOP,A_NOP,A_MULSD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBSD,A_NOP
|
A_NOP,A_NOP,A_ADDSD,A_NOP,A_DIVSD,A_NOP,A_NOP,A_MULSD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBSD,A_NOP,A_NOP,A_NOP
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
( { vectorized/packed }
|
( { vectorized/packed }
|
||||||
@ -1109,10 +1109,10 @@ unit cgx86;
|
|||||||
these
|
these
|
||||||
}
|
}
|
||||||
( { OS_F32 }
|
( { OS_F32 }
|
||||||
A_NOP,A_NOP,A_ADDPS,A_NOP,A_DIVPS,A_NOP,A_NOP,A_MULPS,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBPS,A_XORPS
|
A_NOP,A_NOP,A_ADDPS,A_NOP,A_DIVPS,A_NOP,A_NOP,A_MULPS,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBPS,A_XORPS,A_NOP,A_NOP
|
||||||
),
|
),
|
||||||
( { OS_F64 }
|
( { OS_F64 }
|
||||||
A_NOP,A_NOP,A_ADDPD,A_NOP,A_DIVPD,A_NOP,A_NOP,A_MULPD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBPD,A_XORPD
|
A_NOP,A_NOP,A_ADDPD,A_NOP,A_DIVPD,A_NOP,A_NOP,A_MULPD,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_NOP,A_SUBPD,A_XORPD,A_NOP,A_NOP
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -1259,7 +1259,7 @@ unit cgx86;
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],a,reg));
|
list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],a,reg));
|
||||||
OP_SHL,OP_SHR,OP_SAR:
|
OP_SHL,OP_SHR,OP_SAR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
if (a and 63) <> 0 Then
|
if (a and 63) <> 0 Then
|
||||||
@ -1375,7 +1375,7 @@ unit cgx86;
|
|||||||
else
|
else
|
||||||
list.concat(taicpu.op_const_ref(TOpCG2AsmOp[op],
|
list.concat(taicpu.op_const_ref(TOpCG2AsmOp[op],
|
||||||
TCgSize2OpSize[size],a,tmpref));
|
TCgSize2OpSize[size],a,tmpref));
|
||||||
OP_SHL,OP_SHR,OP_SAR:
|
OP_SHL,OP_SHR,OP_SAR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
if (a and 31) <> 0 then
|
if (a and 31) <> 0 then
|
||||||
list.concat(taicpu.op_const_ref(
|
list.concat(taicpu.op_const_ref(
|
||||||
@ -1407,9 +1407,9 @@ unit cgx86;
|
|||||||
{ special stuff, needs separate handling inside code }
|
{ special stuff, needs separate handling inside code }
|
||||||
{ generator }
|
{ generator }
|
||||||
internalerror(200109233);
|
internalerror(200109233);
|
||||||
OP_SHR,OP_SHL,OP_SAR:
|
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
|
||||||
begin
|
begin
|
||||||
{ Use ecx to load the value, that allows beter coalescing }
|
{ Use ecx to load the value, that allows better coalescing }
|
||||||
getcpuregister(list,NR_ECX);
|
getcpuregister(list,NR_ECX);
|
||||||
a_load_reg_reg(list,size,OS_32,src,NR_ECX);
|
a_load_reg_reg(list,size,OS_32,src,NR_ECX);
|
||||||
list.concat(taicpu.op_reg_reg(Topcg2asmop[op],tcgsize2opsize[size],NR_CL,dst));
|
list.concat(taicpu.op_reg_reg(Topcg2asmop[op],tcgsize2opsize[size],NR_CL,dst));
|
||||||
|
|||||||
@ -1537,3 +1537,31 @@ asm
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef FPC_HAS_INTERNAL_ROX}
|
||||||
|
{ the i386 cg doesn't support yet directly coded 64 bit rotates }
|
||||||
|
function Ror(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shr 1) or (AValue shl 63);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 63;
|
||||||
|
Result:=(AValue shr Dist) or (AValue shl (64-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shl 1) or (AValue shr 63);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 63;
|
||||||
|
Result:=(AValue shl Dist) or (AValue shr (64-Dist));
|
||||||
|
end;
|
||||||
|
{$endif FPC_HAS_INTERNAL_ROX}
|
||||||
|
|||||||
@ -2043,4 +2043,114 @@ procedure WriteBarrier;{$ifdef SYSTEMINLINE}inline;{$endif}
|
|||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$endif}
|
{$endif FPC_SYSTEM_HAS_MEM_BARRIER}
|
||||||
|
|
||||||
|
{$ifndef FPC_HAS_INTERNAL_ROX}
|
||||||
|
{$ifndef FPC_SYSTEM_HAS_ROX}
|
||||||
|
|
||||||
|
function Ror(Const AValue : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shr 1) or (AValue shl 7);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : Byte;Dist : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 7;
|
||||||
|
Result:=(AValue shr Dist) or (AValue shl (8-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shr 1) or (AValue shl 15);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : Word;Dist : Byte): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 15;
|
||||||
|
Result:=(AValue shr Dist) or (AValue shl (16-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shr 1) or (AValue shl 31);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : DWord;Dist : Byte): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 31;
|
||||||
|
Result:=(AValue shr Dist) or (AValue shl (32-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shr 1) or (AValue shl 63);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Ror(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 63;
|
||||||
|
Result:=(AValue shr Dist) or (AValue shl (64-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shl 1) or (AValue shr 7);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : Byte;Dist : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 7;
|
||||||
|
Result:=(AValue shl Dist) or (AValue shr (8-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shl 1) or (AValue shr 15);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : Word;Dist : Byte): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 15;
|
||||||
|
Result:=(AValue shl Dist) or (AValue shr (16-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shl 1) or (AValue shr 31);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : DWord;Dist : Byte): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 31;
|
||||||
|
Result:=(AValue shl Dist) or (AValue shr (32-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Result:=(AValue shl 1) or (AValue shr 63);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function Rol(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
begin
|
||||||
|
Dist:=Dist and 63;
|
||||||
|
Result:=(AValue shl Dist) or (AValue shr (64-Dist));
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$endif FPC_SYSTEM_HAS_ROX}
|
||||||
|
{$endif FPC_HAS_INTERNAL_ROX}
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,10 @@ const
|
|||||||
fpc_in_writestr_x = 62;
|
fpc_in_writestr_x = 62;
|
||||||
fpc_in_readstr_x = 63;
|
fpc_in_readstr_x = 63;
|
||||||
fpc_in_abs_long = 64;
|
fpc_in_abs_long = 64;
|
||||||
|
fpc_in_ror_x = 65;
|
||||||
|
fpc_in_ror_x_x = 66;
|
||||||
|
fpc_in_rol_x = 67;
|
||||||
|
fpc_in_rol_x_x = 68;
|
||||||
|
|
||||||
{ Internal constant functions }
|
{ Internal constant functions }
|
||||||
fpc_in_const_sqr = 100;
|
fpc_in_const_sqr = 100;
|
||||||
|
|||||||
@ -608,6 +608,57 @@ function NtoLE(const AValue: DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
|||||||
function NtoLE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
|
function NtoLE(const AValue: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
function NtoLE(const AValue: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
|
||||||
|
{$ifdef FPC_HAS_INTERNAL_ROX}
|
||||||
|
function Ror(Const AValue : Byte): Byte;[internproc:fpc_in_ror_x];
|
||||||
|
function Ror(Const AValue : Byte;Dist : Byte): Byte;[internproc:fpc_in_ror_x_x];
|
||||||
|
function Ror(Const AValue : Word): Word;[internproc:fpc_in_ror_x];
|
||||||
|
function Ror(Const AValue : Word;Dist : Byte): Word;[internproc:fpc_in_ror_x_x];
|
||||||
|
function Ror(Const AValue : DWord): DWord;[internproc:fpc_in_ror_x];
|
||||||
|
function Ror(Const AValue : DWord;Dist : Byte): DWord;[internproc:fpc_in_ror_x_x];
|
||||||
|
{ the i386 cg doesn't support yet directly coded 64 bit rotates }
|
||||||
|
{$ifndef cpui386}
|
||||||
|
function Ror(Const AValue : QWord): QWord;[internproc:fpc_in_ror_x];
|
||||||
|
function Ror(Const AValue : QWord;Dist : Byte): QWord;[internproc:fpc_in_ror_x_x];
|
||||||
|
{$else cpui386}
|
||||||
|
function Ror(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
{$endif cpui386}
|
||||||
|
|
||||||
|
function Rol(Const AValue : Byte): Byte;[internproc:fpc_in_rol_x];
|
||||||
|
function Rol(Const AValue : Byte;Dist : Byte): Byte;[internproc:fpc_in_rol_x_x];
|
||||||
|
function Rol(Const AValue : Word): Word;[internproc:fpc_in_rol_x];
|
||||||
|
function Rol(Const AValue : Word;Dist : Byte): Word;[internproc:fpc_in_rol_x_x];
|
||||||
|
function Rol(Const AValue : DWord): DWord;[internproc:fpc_in_rol_x];
|
||||||
|
function Rol(Const AValue : DWord;Dist : Byte): DWord;[internproc:fpc_in_rol_x_x];
|
||||||
|
{ the i386 cg doesn't support yet directly coded 64 bit rotates }
|
||||||
|
{$ifndef cpui386}
|
||||||
|
function Rol(Const AValue : QWord): QWord;[internproc:fpc_in_rol_x];
|
||||||
|
function Rol(Const AValue : QWord;Dist : Byte): QWord;[internproc:fpc_in_rol_x_x];
|
||||||
|
{$else cpui386}
|
||||||
|
function Rol(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
{$endif cpui386}
|
||||||
|
|
||||||
|
{$else FPC_HAS_INTERNAL_ROX}
|
||||||
|
function Ror(Const AValue : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : Byte;Dist : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : Word;Dist : Byte): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : DWord;Dist : Byte): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Ror(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
|
||||||
|
function Rol(Const AValue : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : Byte;Dist : Byte): Byte;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : Word): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : Word;Dist : Byte): Word;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : DWord): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : DWord;Dist : Byte): DWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
function Rol(Const AValue : QWord;Dist : Byte): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}
|
||||||
|
{$endif FPC_HAS_INTERNAL_ROX}
|
||||||
|
|
||||||
{$ifndef FPUNONE}
|
{$ifndef FPUNONE}
|
||||||
{ float math routines }
|
{ float math routines }
|
||||||
{$I mathh.inc}
|
{$I mathh.inc}
|
||||||
|
|||||||
78
tests/test/trox1.pp
Normal file
78
tests/test/trox1.pp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
procedure do_error(i : integer);
|
||||||
|
begin
|
||||||
|
writeln('Error: ',i);
|
||||||
|
halt(1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
b1,b2 : byte;
|
||||||
|
w1 : word;
|
||||||
|
d1 : dword;
|
||||||
|
q1 : qword;
|
||||||
|
begin
|
||||||
|
b1:=1;
|
||||||
|
b2:=3;
|
||||||
|
b1:=ror(b1);
|
||||||
|
b1:=ror(b1,2);
|
||||||
|
b1:=ror(b1,b2);
|
||||||
|
if b1<>4 then
|
||||||
|
do_error(1000);
|
||||||
|
|
||||||
|
w1:=1;
|
||||||
|
b2:=3;
|
||||||
|
w1:=ror(w1);
|
||||||
|
w1:=ror(w1,2);
|
||||||
|
w1:=ror(w1,b2);
|
||||||
|
if w1<>$400 then
|
||||||
|
do_error(1001);
|
||||||
|
|
||||||
|
d1:=1;
|
||||||
|
b2:=3;
|
||||||
|
d1:=ror(d1);
|
||||||
|
d1:=ror(d1,2);
|
||||||
|
d1:=ror(d1,b2);
|
||||||
|
if d1<>$4000000 then
|
||||||
|
do_error(1002);
|
||||||
|
|
||||||
|
q1:=1;
|
||||||
|
b2:=3;
|
||||||
|
q1:=ror(q1);
|
||||||
|
q1:=ror(q1,2);
|
||||||
|
q1:=ror(q1,b2);
|
||||||
|
if q1<>$400000000000000 then
|
||||||
|
do_error(1003);
|
||||||
|
|
||||||
|
b1:=1;
|
||||||
|
b2:=3;
|
||||||
|
b1:=rol(b1);
|
||||||
|
b1:=rol(b1,2);
|
||||||
|
b1:=rol(b1,b2);
|
||||||
|
if b1<>$40 then
|
||||||
|
do_error(2000);
|
||||||
|
|
||||||
|
w1:=$8001;
|
||||||
|
b2:=3;
|
||||||
|
w1:=rol(w1);
|
||||||
|
w1:=rol(w1,2);
|
||||||
|
w1:=rol(w1,b2);
|
||||||
|
if w1<>$60 then
|
||||||
|
do_error(2001);
|
||||||
|
|
||||||
|
d1:=$80000001;
|
||||||
|
b2:=3;
|
||||||
|
d1:=rol(d1);
|
||||||
|
d1:=rol(d1,2);
|
||||||
|
d1:=rol(d1,b2);
|
||||||
|
if d1<>$60 then
|
||||||
|
do_error(2002);
|
||||||
|
|
||||||
|
q1:=$8000000000000001;
|
||||||
|
b2:=3;
|
||||||
|
q1:=rol(q1);
|
||||||
|
q1:=rol(q1,2);
|
||||||
|
q1:=rol(q1,b2);
|
||||||
|
if q1<>$60 then
|
||||||
|
do_error(2003);
|
||||||
|
|
||||||
|
writeln('ok');
|
||||||
|
end.
|
||||||
Loading…
Reference in New Issue
Block a user