[su]divsi3 in sh.md
SAITOH Masanobu
masanobu@iij.ad.jp
Thu Jul 6 01:47:00 GMT 2000
Some complexed function becomes wrong under coff-sh
(I tested egcs-20000703, NetBSD/sh3 1.4.1).
zic in tzcode ( ftp://elsie.nci.nih.gov/pub/ ) dies by
bus error when it was compiled with -O1 (-O2 works fine).
The isleap() macro in zic.c::rpytime() will call __sdivsi3().
-------------- a part of zic.c::rpytime() ----------------
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
static time_t
rpytime(rp, wantedy)
register const struct rule * const rp;
register const int wantedy;
{
register int y, m, i;
register long dayoff; /* with a nod to Margaret O. */
register time_t t;
if (wantedy == INT_MIN)
return min_time;
if (wantedy == INT_MAX)
return max_time;
dayoff = 0;
m = TM_JANUARY;
y = EPOCH_YEAR;
while (wantedy != y) {
if (wantedy > y) {
i = len_years[isleap(y)];
++y;
} else {
--y;
i = -len_years[isleap(y)];
}
dayoff = oadd(dayoff, eitol(i));
}
while (m != rp->r_month) {
i = len_months[isleap(y)][m];
dayoff = oadd(dayoff, eitol(i));
++m;
}
.
.
.
--------------------------------------------------------------
--------------------- part of zic.s (-O1) --------------------
L1282:
add #-4,r15
mov.l L1329,r1
jsr @r1
mov r9,r4
mov.l L1330,r1
mov r11,r4
jsr @r1
mov r0,r5
mov r0,r11
add #4,r15
cmp/eq r10,r8
bf L1278
L1277:
mov.l @(24,r12),r1
mov.l @r14,r0
cmp/eq r1,r0
bt L1316
mov.l L1331,r9
mov r10,r4
jsr @r13 <=== r13 is the address of __sdivsi3().
mov #100,r5 But, it doesn't set (the instruction
mov r0,r1 to set r13 appear later of this
shll2 r1 instruction).
mov r1,r8
add r0,r8
.align 2
L1288:
--------------------------------------------------------------
gcc/config/sh/sh.md says:
-------------------- sh.md::divsi3 ---------------------------
(define_expand "divsi3"
[(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
(set (reg:SI 4) (match_operand:SI 1 "general_operand" ""))
(set (reg:SI 5) (match_operand:SI 2 "general_operand" ""))
(parallel [(set (match_operand:SI 0 "register_operand" "")
(div:SI (reg:SI 4)
(reg:SI 5)))
(clobber (reg:SI 18))
(clobber (reg:SI 17))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 3))
(use (match_dup 3))])]
""
"
{
rtx first, last;
operands[3] = gen_reg_rtx(SImode);
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
/***********************************************
It seems following insn IS the "first" insn to
block with REG_LIBCALL-REG_RETVAL
************************************************/
emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
if (TARGET_FPU_SINGLE)
last = gen_divsi3_i4_single (operands[0], operands[3]);
else
last = gen_divsi3_i4 (operands[0], operands[3]);
}
else
{
/***********************************************
It seems following insn IS the "first" insn to
block with REG_LIBCALL-REG_RETVAL
************************************************/
emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
last = gen_divsi3_i1 (operands[0], operands[3]);
}
/***********************************************
It seems following insn ISN'T the "first" insn to
block with REG_LIBCALL-REG_RETVAL
************************************************/
first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
last = emit_insn (last);
/* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
invariant code motion can move it. */
REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
DONE;
}")
-----------------------------------------------------------------------
It seems following patch fixes this problem. Is this correct?
--------------------- patch for udivsi3 and sdivsi3 --------------------
*** sh.md.orig Fri Jun 2 08:14:27 2000
--- sh.md Thu Jul 6 11:17:45 2000
***************
*** 937,943 ****
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
! emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
if (TARGET_FPU_SINGLE)
last = gen_udivsi3_i4_single (operands[0], operands[3]);
--- 937,943 ----
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
! first = emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
if (TARGET_FPU_SINGLE)
last = gen_udivsi3_i4_single (operands[0], operands[3]);
***************
*** 946,956 ****
}
else
{
! emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
last = gen_udivsi3_i1 (operands[0], operands[3]);
}
! first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
last = emit_insn (last);
/* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
--- 946,956 ----
}
else
{
! first = emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
last = gen_udivsi3_i1 (operands[0], operands[3]);
}
! emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
last = emit_insn (last);
/* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
***************
*** 1023,1029 ****
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
! emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
if (TARGET_FPU_SINGLE)
last = gen_divsi3_i4_single (operands[0], operands[3]);
--- 1023,1029 ----
/* Emit the move of the address to a pseudo outside of the libcall. */
if (TARGET_HARD_SH4)
{
! first = emit_move_insn (operands[3],
gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
if (TARGET_FPU_SINGLE)
last = gen_divsi3_i4_single (operands[0], operands[3]);
***************
*** 1032,1041 ****
}
else
{
! emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
last = gen_divsi3_i1 (operands[0], operands[3]);
}
! first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
last = emit_insn (last);
/* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
--- 1032,1041 ----
}
else
{
! first = emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
last = gen_divsi3_i1 (operands[0], operands[3]);
}
! emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
last = emit_insn (last);
/* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
-----------------------------------------------------------------------
But, a new problem occurred after this patch was applied.
Followin programs doesn't work when it compiled with -O1
(-O2 works fine).
------ test code for new patch -----------
#include <stdio.h>
#include <stdlib.h>
int g = 1;
int
main()
{
int a = 1, b = 1;
#define DIV(g) (g * 8 / 3)
printf("--- a = %d, DIV = %d\n", a, DIV(g));
printf("--- (a > DIV) = %d\n", a > DIV(g));
while (a > DIV(g)) {
printf("why?\n");
if (b == 1)
break;
}
return 0;
}
-----------------
-------------- gcc -O2 -S ----------------
.file "wh2.c"
.data
gcc2_compiled.:
___gnu_compiled_c:
.global _g
.align 2
_g:
.long 1
.text
.align 2
LC0:
.ascii "--- a = %d, DIV = %d\12\0"
.align 2
LC1:
.ascii "--- (a > DIV) = %d\12\0"
.align 2
LC2:
.ascii "why?\12\0"
.align 2
.global _main
_main:
mov.l r8,@-r15
mov.l r9,@-r15
mov.l r10,@-r15
mov.l r11,@-r15
mov.l r12,@-r15
mov.l r14,@-r15
sts.l pr,@-r15
mov.l L11,r1
jsr @r1
mov r15,r14
mov #1,r10
mov r10,r11
add #-4,r15
mov.l L12,r8
mov.l @r8,r4
mov.l L13,r7
shll2 r4
add r4,r4
jsr @r7
mov #3,r5
mov.l L14,r9
mov.l L15,r4
mov r10,r5
jsr @r9
mov r0,r6
mov.l @r8,r4
mov.l L13,r7
shll2 r4
add r4,r4
jsr @r7
mov #3,r5
cmp/gt r0,r10
mov.l L16,r4
jsr @r9
movt r5
add #4,r15
mov r9,r8
.align 2
L10:
cmp/gt r12,r11 <= r12 is uninitialized
bf L8
mov.l L17,r4
jsr @r8
add #-4,r15
add #4,r15
mov r10,r0
cmp/eq #1,r0
bf L10
L8:
mov #0,r0
mov r14,r15
lds.l @r15+,pr
mov.l @r15+,r14
mov.l @r15+,r12
mov.l @r15+,r11
mov.l @r15+,r10
mov.l @r15+,r9
rts
mov.l @r15+,r8
L18:
.align 2
L11:
.long ___main
L12:
.long _g
L13:
.long ___sdivsi3
L14:
.long _printf
L15:
.long LC0
L16:
.long LC1
L17:
.long LC2
------------------------------------------
I don't know how to solve this problem.
----------------------------------------------------------
SAITOH Masanobu (masanobu@iij.ad.jp
msaitoh@netbsd.org)
More information about the Gcc-bugs
mailing list