|
@@ -105,6 +105,9 @@ unit cgcpu;
|
|
(* NOT IN USE: *)
|
|
(* NOT IN USE: *)
|
|
procedure g_return_from_proc_mac(list : TAsmList;parasize : aint);
|
|
procedure g_return_from_proc_mac(list : TAsmList;parasize : aint);
|
|
|
|
|
|
|
|
+ { clear out potential overflow bits from 8 or 16 bit operations }
|
|
|
|
+ { the upper 24/16 bits of a register after an operation }
|
|
|
|
+ procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
|
|
|
|
|
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
|
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
|
{ base to the value of the index if (base = R_NO). }
|
|
{ base to the value of the index if (base = R_NO). }
|
|
@@ -516,21 +519,30 @@ const
|
|
var
|
|
var
|
|
instr: taicpu;
|
|
instr: taicpu;
|
|
begin
|
|
begin
|
|
- case tosize of
|
|
|
|
- OS_8:
|
|
|
|
- instr := taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
|
- reg2,reg1,0,31-8+1,31);
|
|
|
|
- OS_S8:
|
|
|
|
- instr := taicpu.op_reg_reg(A_EXTSB,reg2,reg1);
|
|
|
|
- OS_16:
|
|
|
|
- instr := taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
|
- reg2,reg1,0,31-16+1,31);
|
|
|
|
- OS_S16:
|
|
|
|
- instr := taicpu.op_reg_reg(A_EXTSH,reg2,reg1);
|
|
|
|
- OS_32,OS_S32:
|
|
|
|
- instr := taicpu.op_reg_reg(A_MR,reg2,reg1);
|
|
|
|
- else internalerror(2002090901);
|
|
|
|
- end;
|
|
|
|
|
|
+ if (tcgsize2size[fromsize] > tcgsize2size[tosize]) or
|
|
|
|
+ ((tcgsize2size[fromsize] = tcgsize2size[tosize]) and
|
|
|
|
+ (fromsize <> tosize)) or
|
|
|
|
+ { needs to mask out the sign in the top 16 bits }
|
|
|
|
+ ((fromsize = OS_S8) and
|
|
|
|
+ (tosize = OS_16)) then
|
|
|
|
+ case tosize of
|
|
|
|
+ OS_8:
|
|
|
|
+ instr := taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
|
+ reg2,reg1,0,31-8+1,31);
|
|
|
|
+ OS_S8:
|
|
|
|
+ instr := taicpu.op_reg_reg(A_EXTSB,reg2,reg1);
|
|
|
|
+ OS_16:
|
|
|
|
+ instr := taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
|
+ reg2,reg1,0,31-16+1,31);
|
|
|
|
+ OS_S16:
|
|
|
|
+ instr := taicpu.op_reg_reg(A_EXTSH,reg2,reg1);
|
|
|
|
+ OS_32,OS_S32:
|
|
|
|
+ instr := taicpu.op_reg_reg(A_MR,reg2,reg1);
|
|
|
|
+ else internalerror(2002090901);
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ instr := taicpu.op_reg_reg(A_MR,reg2,reg1);
|
|
|
|
+
|
|
list.concat(instr);
|
|
list.concat(instr);
|
|
rg[R_INTREGISTER].add_move_instruction(instr);
|
|
rg[R_INTREGISTER].add_move_instruction(instr);
|
|
end;
|
|
end;
|
|
@@ -611,6 +623,16 @@ const
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ procedure tcgppc.maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
|
|
|
+ const
|
|
|
|
+ overflowops = [OP_MUL,OP_SHL,OP_ADD,OP_SUB,OP_NOT,OP_NEG];
|
|
|
|
+ begin
|
|
|
|
+ if (op in overflowops) and
|
|
|
|
+ (size in [OS_8,OS_S8,OS_16,OS_S16]) then
|
|
|
|
+ a_load_reg_reg(list,OS_32,size,dst,dst);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
procedure tcgppc.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
|
|
procedure tcgppc.a_op_const_reg_reg(list: TAsmList; op: TOpCg;
|
|
size: tcgsize; a: aint; src, dst: tregister);
|
|
size: tcgsize; a: aint; src, dst: tregister);
|
|
var
|
|
var
|
|
@@ -651,9 +673,23 @@ const
|
|
begin
|
|
begin
|
|
case op of
|
|
case op of
|
|
OP_OR:
|
|
OP_OR:
|
|
- list.concat(taicpu.op_reg_const(A_LI,dst,-1));
|
|
|
|
|
|
+ case size of
|
|
|
|
+ OS_8, OS_S8:
|
|
|
|
+ list.concat(taicpu.op_reg_const(A_LI,dst,255));
|
|
|
|
+ OS_16, OS_S16:
|
|
|
|
+ a_load_const_reg(list,OS_16,65535,dst);
|
|
|
|
+ else
|
|
|
|
+ list.concat(taicpu.op_reg_const(A_LI,dst,-1));
|
|
|
|
+ end;
|
|
OP_XOR:
|
|
OP_XOR:
|
|
- list.concat(taicpu.op_reg_reg(A_NOT,dst,src));
|
|
|
|
|
|
+ case size of
|
|
|
|
+ OS_8, OS_S8:
|
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src,255));
|
|
|
|
+ OS_16, OS_S16:
|
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src,65535));
|
|
|
|
+ else
|
|
|
|
+ list.concat(taicpu.op_reg_reg(A_NOT,dst,src));
|
|
|
|
+ end;
|
|
OP_AND:
|
|
OP_AND:
|
|
a_load_reg_reg(list,size,size,src,dst);
|
|
a_load_reg_reg(list,size,size,src,dst);
|
|
end;
|
|
end;
|
|
@@ -663,7 +699,13 @@ const
|
|
((op <> OP_AND) or
|
|
((op <> OP_AND) or
|
|
not gotrlwi) then
|
|
not gotrlwi) then
|
|
begin
|
|
begin
|
|
|
|
+ if ((size = OS_8) and
|
|
|
|
+ (byte(a) <> a)) or
|
|
|
|
+ ((size = OS_S8) and
|
|
|
|
+ (shortint(a) <> a)) then
|
|
|
|
+ internalerror(200604142);
|
|
list.concat(taicpu.op_reg_reg_const(oplo,dst,src,word(a)));
|
|
list.concat(taicpu.op_reg_reg_const(oplo,dst,src,word(a)));
|
|
|
|
+ { and/or/xor -> cannot overflow in high 16 bits }
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
{ all basic constant instructions also have a shifted form that }
|
|
{ all basic constant instructions also have a shifted form that }
|
|
@@ -673,6 +715,8 @@ const
|
|
(not(op = OP_AND) or
|
|
(not(op = OP_AND) or
|
|
not gotrlwi) then
|
|
not gotrlwi) then
|
|
begin
|
|
begin
|
|
|
|
+ if (size in [OS_8,OS_S8,OS_16,OS_S16]) then
|
|
|
|
+ internalerror(200604141);
|
|
list.concat(taicpu.op_reg_reg_const(ophi,dst,src,word(a shr 16)));
|
|
list.concat(taicpu.op_reg_reg_const(ophi,dst,src,word(a shr 16)));
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
@@ -687,6 +731,7 @@ const
|
|
(a <= high(smallint)) then
|
|
(a <= high(smallint)) then
|
|
begin
|
|
begin
|
|
list.concat(taicpu.op_reg_reg_const(A_ADDI,dst,src,smallint(a)));
|
|
list.concat(taicpu.op_reg_reg_const(A_ADDI,dst,src,smallint(a)));
|
|
|
|
+ maybeadjustresult(list,op,size,dst);
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -783,6 +828,7 @@ const
|
|
a_load_const_reg(list,OS_32,a,scratchreg);
|
|
a_load_const_reg(list,OS_32,a,scratchreg);
|
|
a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst);
|
|
a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst);
|
|
end;
|
|
end;
|
|
|
|
+ maybeadjustresult(list,op,size,dst);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -809,6 +855,7 @@ const
|
|
else
|
|
else
|
|
list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
|
|
list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
|
|
end;
|
|
end;
|
|
|
|
+ maybeadjustresult(list,op,size,dst);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|