cleaned up, reindented, simplified and allowed some minor optimizations in tcg64f68k

git-svn-id: trunk@26914 -
This commit is contained in:
Károly Balogh 2014-03-01 18:25:05 +00:00
parent 73e6ffe675
commit bd4cc3b8f3

View File

@ -157,6 +157,28 @@ unit cgcpu;
A_NONE
);
{ opcode with extend bits table lookup, used by 64bit cg }
topcg2tasmopx: Array[topcg] of tasmop =
(
A_NONE,
A_NONE,
A_ADDX,
A_NONE,
A_NONE,
A_NONE,
A_NONE,
A_NONE,
A_NEGX,
A_NONE,
A_NONE,
A_NONE,
A_NONE,
A_NONE,
A_SUBX,
A_NONE,
A_NONE,
A_NONE
);
TOpCmp2AsmCond: Array[topcmp] of TAsmCond =
(
@ -1669,9 +1691,9 @@ unit cgcpu;
begin
localsize := current_procinfo.calc_stackframe_size;
list.concat(taicpu.op_reg(A_UNLK,S_NO,NR_FRAME_POINTER_REG));
parasize := parasize - target_info.first_parm_offset; { i'm still not 100% confident that this is
correct here, but at least it looks less
hacky, and makes some sense (KB) }
parasize := parasize - target_info.first_parm_offset; { i'm still not 100% confident that this is
correct here, but at least it looks less
hacky, and makes some sense (KB) }
if (parasize<>0) then
begin
{ only 68020+ supports RTD, so this needs another code path
@ -1985,156 +2007,127 @@ unit cgcpu;
{****************************************************************************}
{ TCG64F68K }
{****************************************************************************}
procedure tcg64f68k.a_op64_reg_reg(list : TAsmList;op:TOpCG;size: tcgsize; regsrc,regdst : tregister64);
var
hreg1, hreg2 : tregister;
opcode : tasmop;
instr : taicpu;
begin
// writeln('a_op64_reg_reg');
opcode := topcg2tasmop[op];
case op of
OP_ADD :
begin
{ if one of these three registers is an address
register, we'll really get into problems!
}
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) or
isaddressregister(regsrc.reghi) then
internalerror(20020817);
list.concat(taicpu.op_reg_reg(A_ADD,S_L,regsrc.reglo,regdst.reglo));
list.concat(taicpu.op_reg_reg(A_ADDX,S_L,regsrc.reghi,regdst.reghi));
end;
OP_AND,OP_OR :
begin
{ at least one of the registers must be a data register }
if (isaddressregister(regdst.reglo) and
isaddressregister(regsrc.reglo)) or
(isaddressregister(regsrc.reghi) and
isaddressregister(regdst.reghi))
then
internalerror(20020817);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reglo,regdst.reglo);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reghi,regdst.reghi);
end;
{ this is handled in 1st pass for 32-bit cpu's (helper call) }
OP_IDIV,OP_DIV,
OP_IMUL,OP_MUL: internalerror(2002081701);
{ this is also handled in 1st pass for 32-bit cpu's (helper call) }
OP_SAR,OP_SHL,OP_SHR: internalerror(2002081702);
OP_SUB:
begin
{ if one of these three registers is an address
register, we'll really get into problems!
}
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) or
isaddressregister(regsrc.reghi) then
internalerror(20020817);
list.concat(taicpu.op_reg_reg(A_SUB,S_L,regsrc.reglo,regdst.reglo));
list.concat(taicpu.op_reg_reg(A_SUBX,S_L,regsrc.reghi,regdst.reghi));
end;
OP_XOR:
begin
if isaddressregister(regdst.reglo) or
isaddressregister(regsrc.reglo) or
isaddressregister(regsrc.reghi) or
isaddressregister(regdst.reghi) then
internalerror(20020817);
list.concat(taicpu.op_reg_reg(A_EOR,S_L,regsrc.reglo,regdst.reglo));
list.concat(taicpu.op_reg_reg(A_EOR,S_L,regsrc.reghi,regdst.reghi));
end;
OP_NEG:
begin
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) then
internalerror(2012110402);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reglo,regdst.reglo);
cg.add_move_instruction(instr);
list.concat(instr);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reghi,regdst.reghi);
cg.add_move_instruction(instr);
list.concat(instr);
list.concat(taicpu.op_reg(A_NEG,S_L,regdst.reglo));
list.concat(taicpu.op_reg(A_NEGX,S_L,regdst.reghi));
end;
OP_NOT:
begin
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) then
internalerror(2012110401);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reglo,regdst.reglo);
cg.add_move_instruction(instr);
list.concat(instr);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reghi,regdst.reghi);
cg.add_move_instruction(instr);
list.concat(instr);
list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reglo));
list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reghi));
end;
end; { end case }
end;
procedure tcg64f68k.a_op64_reg_reg(list : TAsmList;op:TOpCG;size: tcgsize; regsrc,regdst : tregister64);
var
hreg1, hreg2 : tregister;
opcode : tasmop;
xopcode : tasmop;
instr : taicpu;
begin
opcode := topcg2tasmop[op];
xopcode := topcg2tasmopx[op];
case op of
OP_ADD,OP_SUB:
begin
{ if one of these three registers is an address
register, we'll really get into problems! }
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) or
isaddressregister(regsrc.reghi) then
internalerror(2014030101);
list.concat(taicpu.op_reg_reg(opcode,S_L,regsrc.reglo,regdst.reglo));
list.concat(taicpu.op_reg_reg(xopcode,S_L,regsrc.reghi,regdst.reghi));
end;
OP_AND,OP_OR:
begin
{ at least one of the registers must be a data register }
if (isaddressregister(regdst.reglo) and
isaddressregister(regsrc.reglo)) or
(isaddressregister(regsrc.reghi) and
isaddressregister(regdst.reghi)) then
internalerror(2014030102);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reglo,regdst.reglo);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reghi,regdst.reghi);
end;
{ this is handled in 1st pass for 32-bit cpu's (helper call) }
OP_IDIV,OP_DIV,
OP_IMUL,OP_MUL:
internalerror(2002081701);
{ this is also handled in 1st pass for 32-bit cpu's (helper call) }
OP_SAR,OP_SHL,OP_SHR:
internalerror(2002081702);
OP_XOR:
begin
if isaddressregister(regdst.reglo) or
isaddressregister(regsrc.reglo) or
isaddressregister(regsrc.reghi) or
isaddressregister(regdst.reghi) then
internalerror(2014030103);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reglo,regdst.reglo);
cg.a_op_reg_reg(list,op,OS_32,regsrc.reghi,regdst.reghi);
end;
OP_NEG,OP_NOT:
begin
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) then
internalerror(2014030104);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reglo,regdst.reglo);
cg.add_move_instruction(instr);
list.concat(instr);
instr:=taicpu.op_reg_reg(A_MOVE,S_L,regsrc.reghi,regdst.reghi);
cg.add_move_instruction(instr);
list.concat(instr);
if (op = OP_NOT) then
xopcode:=opcode;
list.concat(taicpu.op_reg(opcode,S_L,regdst.reglo));
list.concat(taicpu.op_reg(xopcode,S_L,regdst.reghi));
end;
end; { end case }
end;
procedure tcg64f68k.a_op64_const_reg(list : TAsmList;op:TOpCG;size: tcgsize; value : int64;regdst : tregister64);
var
lowvalue : cardinal;
highvalue : cardinal;
hreg : tregister;
begin
// writeln('a_op64_const_reg');
{ is it optimized out ? }
// if cg.optimize64_op_const_reg(list,op,value,reg) then
// exit;
procedure tcg64f68k.a_op64_const_reg(list : TAsmList;op:TOpCG;size: tcgsize; value : int64;regdst : tregister64);
var
lowvalue : cardinal;
highvalue : cardinal;
opcode : tasmop;
xopcode : tasmop;
hreg : tregister;
begin
{ is it optimized out ? }
{ optimize64_op_const_reg doesn't seem to be used in any cg64f32 right now. why? (KB) }
{ if cg.optimize64_op_const_reg(list,op,value,reg) then
exit; }
lowvalue := cardinal(value);
highvalue:= value shr 32;
lowvalue := cardinal(value);
highvalue := value shr 32;
{ the destination registers must be data registers }
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) then
internalerror(20020817);
case op of
OP_ADD :
begin
hreg:=cg.getintregister(list,OS_INT);
list.concat(taicpu.op_const_reg(A_MOVE,S_L,highvalue,hreg));
list.concat(taicpu.op_const_reg(A_ADD,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_reg_reg(A_ADDX,S_L,hreg,regdst.reghi));
end;
OP_AND :
begin
list.concat(taicpu.op_const_reg(A_AND,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_const_reg(A_AND,S_L,highvalue,regdst.reghi));
end;
OP_OR :
begin
list.concat(taicpu.op_const_reg(A_OR,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_const_reg(A_OR,S_L,highvalue,regdst.reghi));
end;
{ this is handled in 1st pass for 32-bit cpus (helper call) }
OP_IDIV,OP_DIV,
OP_IMUL,OP_MUL: internalerror(2002081701);
{ this is also handled in 1st pass for 32-bit cpus (helper call) }
OP_SAR,OP_SHL,OP_SHR: internalerror(2002081702);
OP_SUB:
begin
hreg:=cg.getintregister(list,OS_INT);
list.concat(taicpu.op_const_reg(A_MOVE,S_L,highvalue,hreg));
list.concat(taicpu.op_const_reg(A_SUB,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_reg_reg(A_SUBX,S_L,hreg,regdst.reghi));
end;
OP_XOR:
begin
list.concat(taicpu.op_const_reg(A_EOR,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_const_reg(A_EOR,S_L,highvalue,regdst.reghi));
end;
{ these should have been handled already by earlier passes }
OP_NOT, OP_NEG:
internalerror(2012110403);
end; { end case }
end;
opcode := topcg2tasmop[op];
xopcode := topcg2tasmopx[op];
{ the destination registers must be data registers }
if isaddressregister(regdst.reglo) or
isaddressregister(regdst.reghi) then
internalerror(2014030105);
case op of
OP_ADD,OP_SUB:
begin
hreg:=cg.getintregister(list,OS_INT);
{ cg.a_load_const_reg provides optimized loading to register for special cases }
cg.a_load_const_reg(list,OS_S32,longint(highvalue),hreg);
{ don't use cg.a_op_const_reg() here, because a possible optimized
ADDQ/SUBQ wouldn't set the eXtend bit }
list.concat(taicpu.op_const_reg(opcode,S_L,lowvalue,regdst.reglo));
list.concat(taicpu.op_reg_reg(xopcode,S_L,hreg,regdst.reghi));
end;
OP_AND,OP_OR,OP_XOR:
begin
cg.a_op_const_reg(list,op,OS_S32,longint(lowvalue),regdst.reglo);
cg.a_op_const_reg(list,op,OS_S32,longint(highvalue),regdst.reghi);
end;
{ this is handled in 1st pass for 32-bit cpus (helper call) }
OP_IDIV,OP_DIV,
OP_IMUL,OP_MUL:
internalerror(2002081701);
{ this is also handled in 1st pass for 32-bit cpus (helper call) }
OP_SAR,OP_SHL,OP_SHR:
internalerror(2002081702);
{ these should have been handled already by earlier passes }
OP_NOT,OP_NEG:
internalerror(2012110403);
end; { end case }
end;
procedure create_codegen;