🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.help
Article #52398

Help needed -- stack machine, no pre_dec addressing

#52398
From: Michael Gersten
Date: Sat, 17 Oct 1992 19:23
163 lines
5459 bytes
I have a machine with a stack, and no pre_decrement addressing other than  
stack pushes, that I cannot get gcc to compile code for.

Originally, I had no pre_dec's in my md file, nor did I have #define  
HAVE_PRE_DECREMENT. But I discovered while compiling __muldi3 that gcc assumes  
it can use a pre_dec to push stack operands. So I added

(define_insn ""
        [ (set (mem:HI (pre_dec:HI (reg:HI 15)))
                (match_operand:HI 0 "general_operand" "r")
        )]
        ""
        "       PSHM    %0,%0"
)

(define_insn ""
        [ (set (mem:SI (pre_dec:HI (reg:HI 15)))
                (match_operand:SI 0 "general_operand" "r")
        )]
        ""
        "*
        int r=REGNO(operands[0]);
        char *s=alloca(200);
        char *t;
        sprintf(s, \"   PSHM    R%d,R%d\", r, r+1);
        t = strdup(s);
        return t;
        "
)

to my md, and then __muldi3 was compiled fine.

The next routine in the library, __divdi3, was not so nice. After removing the  
inline call to __negdi2 (just declaring it external), I had in my .rtl dump  
(first pass)

(insn 31 30 32 (set (mem:HI (pre_dec:HI (reg:HI 15)))
       (mem/s:HI (plus:HI (reg:HI 17)
               (const_int -6)))) -1 (nil)
   (nil))

which isn't a problem -- compile it as
(set (scratch_reg) (mem/s:HI (plus:HI (reg:HI 17)
               (const_int -6))))
(set (mem:HI (pre_dec:HI (reg:HI 15))) (scratch_reg))

Except that GO_IF_LEGITIMATE_ADDRESS was passed things like:
Debug: Leg Addr failed for

(plus:HI (pre_dec:HI (reg:HI 15))
   (const_int 1))

After the (const_int 1), came (const_int 2), (const_int 3),
and then it repeated about 20 times. Note that at this point,  
HAVE_PRE_DECREMENT was still false, and the only places that pre_dec appeared  
in the md file was in an unnamed pattern solely to match stack pushes.  
Ultimately, it crashed with

x-temp.c: In function `__divdi3':
x-temp.c:102: internal error--unrecognizable insn:

(insn 32 31 33 (set (reg:HI 25)
       (pre_dec:HI (reg:HI 15))) -1 (nil)
   (nil))


I then modified GO_IF_LEGITIMATE_ADDRESS to accept an address consisting of  
(pre_dec (reg 15)), thinking that maybe that was the problem (note that it  
never produced a "not matched" debugging complaint), and also defined  
HAVE_PRE_DECREMENT.

The result was still the same:
Debug: Leg Addr failed for

(plus:HI (pre_dec:HI (reg:HI 15))
   (const_int 1))
....
x-temp.c: In function `__divdi3':
x-temp.c:102: internal error--unrecognizable insn:

(insn 32 31 33 (set (reg:HI 25)
       (pre_dec:HI (reg:HI 15))) -1 (nil)
   (nil))

It seems that the compiler, faced with computing (push (r17-6)), instead of  
computing (x=(r17-6), push x) is instead computing 

(get_addr(push), (addr) = (r17-6)).
Here is the .i file that was feed to cc1:

enum reg_class { NO_REGS,  INDEX_REG, 

                BASE_INDEX_REG, R2_REG, ALL_REGS, 

                LIM_REG_CLASSES};
enum mode_types { R_mode, B_mode, BX_mode, ISP_mode, ISN_mode,
                D_mode, DX_mode, IM_mode, IMX_mode, I_mode, IX_mode };
typedef enum mode_types mode_types;

extern struct rtx_def *  gen_beq ();
extern struct rtx_def *  gen_bne ();
extern struct rtx_def *  gen_bgt ();
extern struct rtx_def *  gen_bgtu ();
extern struct rtx_def *  gen_blt ();
extern struct rtx_def *  gen_bltu ();
extern struct rtx_def *  gen_bge ();
extern struct rtx_def *  gen_bgeu ();
extern struct rtx_def *  gen_ble ();
extern struct rtx_def *  gen_bleu ();
extern int strict_test;  

extern mode_types what_mode();
extern enum reg_class regno_reg_class[];
extern char *make1Ins(struct rtx_def *  [], char *, int);
extern char *make2Ins(struct rtx_def *  [], char *, int);
extern char *makeIns(struct rtx_def *  [], char *, int, char *);
extern char *makeCompare(struct rtx_def * , struct rtx_def * [], char *, int);
extern char *strdup(char *);
typedef long int ptrdiff_t;
typedef long unsigned int size_t;
typedef int wchar_t;

  struct longlong {long high, low;};
typedef union
{
  struct longlong s;
  long long ll;
} long_long;
extern const unsigned char __clz_tab[];


extern long long __fixunssfdi (float a);
extern long long __fixunsdfdi (double a);
extern long long __negdi2 (long long u);




unsigned long long __udivmoddi4 ();
long long
__divdi3 (u, v)
     long long u, v;
{
  int c = 0;
  long_long uu, vv;
  long long w;
  uu.ll = u;
  vv.ll = v;
  if (uu.s.high < 0)
    c = ~c,
    uu.ll = __negdi2 (uu.ll);
  if (vv.s.high < 0)
    c = ~c,
    vv.ll = __negdi2 (vv.ll);
  w = __udivmoddi4 (uu.ll, vv.ll, (unsigned long long *) 0);
  if (c)
    w = __negdi2 (w);
  return w;
}
--
		Michael Gersten		michael@stb.info.com
HELLO! I'm a signature virus! Join in the fun and copy me into yours!
ex:.-1,. w $HOME/.signature
Technical Details
Message-ID: <m0mgJk6-0005OXC@stb.info.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!stb.INfo.COM!michael

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,d4ac29d1a57cd888,start
X-Google-Attributes: gid11318c,public
X-Google-ArrivalTime: 1992-10-17 07:53:52 PST
Newsgroups: gnu.gcc.help
Path: arc1-ca.pugleaf.net!sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!stb.INfo.COM!michael
From: michael@stb.INfo.COM (Michael Gersten)
Subject: Help needed -- stack machine, no pre_dec addressing
Message-ID: <m0mgJk6-0005OXC@stb.info.com>
Sender: daemon@cis.ohio-state.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sat, 17 Oct 1992 19:23:00 GMT
Lines: 163