Commit ff9350e7 by Linas Vepstas Committed by Richard Henderson

Linas Vepstas <linas@linas.org>

        * README: Add section discussing status of ELF ABI.
        * i370.c: Fix misc spelling mistakes.
        (i370_label_scan): Updated notes, exception handling.
        (i370_function_prolog): Simplify ELF stack handling.
        * i370.h: (FIXED_REGISTERS): Free up r12 for ELF.
        (STACK_GROWS_DOWNWARD): ELF stack grows down.
        (ASM_DECLARE_FUNCTION_NAME): Fix crazy malloc size.
        * i370.md: (movdi): Add notes.
        (floatsidf2): Use stack not rtca for scratch float area.
        (iorsi3): Correct operand constraints.
        * x-oe: Restore TAROUTOPTS which are used by pax.

From-SVN: r29185
parent c8023011
Tue Sep 7 23:23:15 1999 Linas Vepstas <linas@linas.org>
* README: Add section discussing status of ELF ABI.
* i370.c: Fix misc spelling mistakes.
(i370_label_scan): Updated notes, exception handling.
(i370_function_prolog): Simplify ELF stack handling.
* i370.h: (FIXED_REGISTERS): Free up r12 for ELF.
(STACK_GROWS_DOWNWARD): ELF stack grows down.
(ASM_DECLARE_FUNCTION_NAME): Fix crazy malloc size.
* i370.md: (movdi): Add notes.
(floatsidf2): Use stack not rtca for scratch float area.
(iorsi3): Correct operand constraints.
* x-oe: Restore TAROUTOPTS which are used by pax.
Tue Sep 7 22:39:18 1999 Mark Mitchell <mark@codesourcery.com>
* rs6000.c: Include ggc.h.
......@@ -1317,11 +1331,11 @@ Sat Aug 28 16:24:31 1999 Richard Henderson <rth@cygnus.com>
Sat Aug 28 16:20:12 1999 Richard Henderson <rth@cygnus.com>
* haifa-sched.c (sched_analyze): Clear LOG_LINKS before calling
sched_analyze_insn.
(sched_analyze_1): Let add_dependence care for not adding dups.
(sched_analyze_2): Likewise.
(add_branch_dependences): Likewise.
* haifa-sched.c (sched_analyze): Clear LOG_LINKS before calling
sched_analyze_insn.
(sched_analyze_1): Let add_dependence care for not adding dups.
(sched_analyze_2): Likewise.
(add_branch_dependences): Likewise.
Sat Aug 28 15:58:16 1999 Mumit Khan <khan@xraylith.wisc.edu>
......
......@@ -30,9 +30,47 @@ OpenEdition Hints
The shell script "install" is handy for users of OpenEdition.
The ELF ABI
-----------
This compiler, in conjunction with the gas/binutils assembler, defines
a defacto ELF-based ABI for the ESA/390 architecture. Be warned: this
ABI has several major faults. It should be fixed. As it is fixed,
it is subject to change without warning. You should not commit to major
software systems without further exploring and fixing these problems.
Here are some of the problems:
-- No support for shared libraries or dynamically loadable objects.
This is because the compiler currently places address literals in
the text section. Although the GAS assembler supports a syntax for
USING that will place address literals in the data section, this forces
the use of two base registers, one for branches and one for the literal
pool. Work is needed to redesign the function prologue, epilogue and the
base register reloads to minimize the currently excessive use of reserved
registers.
I beleive the best solution would be to add a toc or plt, and extending
the meaning of the USING directive to encompass this. This would
allow the continued use of the human-readable and familiar practice
of using =A() and =F'' to denote address literals, as opposed to more
difficult jump-table notation.
-- the stackframe is almost twice as big as it needs to be.
-- currently, r15 is used to return 32-bit values. Because this is the
last register, it prevents 64-bit ints and small structures from being
returned in registers, forcing return in memory. It would be more
efficient to use r14 to return 32-bit values, and r14+r15 to return
64-bit values.
-- all arguments are currently passed in memory. It would be more efficient
to pass arguments in registers.
ChangeLog
---------
Oct98-Dec98 -- add ELF back end; work on getting ABI more or less correct.
Oct98-Dec98 -- add ELF back end; work on getting ABI more or less functional.
98.12.05 -- fix numerous MVC bugs
99.02.06 -- multiply insn sometimes not generated when needed.
-- extendsidi bugs, bad literal values printed
......
......@@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */
#include "insn-flags.h"
#include "output.h"
#include "insn-attr.h"
#include "function.h"
/* #include "function.h" */
#include "flags.h"
#include "recog.h"
......@@ -370,13 +370,13 @@ i370_short_branch (insn)
/* The i370_label_scan() routine is supposed to loop over
all labels and label references in a compilation unit,
and determine whether all label refs appear on the same
code page as the label. If they do, thenm we can avoid
code page as the label. If they do, then we can avoid
a reload of the base register for that label.
Note that the instruciton addresses used here are only
Note that the instruction addresses used here are only
approximate, and make the sizes of the jumps appear
farther apart then they will actually be. This makes
this code far more conservative than it needed to be.
this code far more conservative than it needs to be.
*/
#define I370_RECORD_LABEL_REF(label,addr) { \
......@@ -470,8 +470,8 @@ i370_label_scan (void)
can only lead to horrible results if this were to occur.
However, the current situation is not any worse than it was
last week, and so we punt for now.
*/
last week, and so we punt for now. */
debug_rtx (insn);
// abort();
for (j=0; j < XVECLEN (body, 0); j++)
......@@ -483,23 +483,30 @@ i370_label_scan (void)
}
else
{
/* The following appears during make of _eh in libgcc2.a
while not obviously wrong, its weird, so not obviously
right either ...
(jump_insn:HI 125 124 126 (set (pc)
(mem:SI (plus:SI (reg/v:SI 1 r1)
(const_int 4)))) 144 {indirect_jump} (nil)
*/
/* XXX hack alert.
Compiling the execption handling (L_eh) in libgcc2.a will trip
up right here, with something that looks like
(set (pc) (mem:SI (plus:SI (reg/v:SI 1 r1) (const_int 4))))
{indirect_jump}
I'm not sure of what leads up to this, but it looks like
the makings of a long jump which will surely get us into trouble
because the base & page registers don't get reloaded. For now
I'm not sure of what to do ... again we punt ... we are not worse
off than yesterday. */
/* print_rtl_single (stdout, insn); */
debug_rtx (insn);
// abort();
/* abort(); */
continue;
}
}
/* At this point, this jump_insn had better be a plain-old
* ordinary one, grap the label id and go */
if (CODE_LABEL != GET_CODE (label)) abort ();
I370_RECORD_LABEL_REF(label,here);
else
{
/* At this point, this jump_insn had better be a plain-old
ordinary one, grap the label id and go */
if (CODE_LABEL != GET_CODE (label)) abort ();
I370_RECORD_LABEL_REF(label,here);
}
}
/* Sometimes, we take addresses of labels and use them
......@@ -1364,11 +1371,11 @@ i370_function_prolog (f, l)
#ifdef TARGET_ELF_ABI
/*
The 370_function_prolog() routine generates the current ELF ABI ES/390 prolog.
It implements a stack that grows downward.
It performs the following steps:
-- saves the callers non-volatile registers on the callers stack.
-- computes a new stack top and checks for room for the stack.
-- initializes size and backpointer of new stack frame
-- updates stack pointer to point at new frame.
-- subtracts stackframe size from the stack pointer.
-- stores backpointer to old caller stack.
XXX hack alert -- if the global var int leaf_function is non-zero,
then this is a leaf, and it might be possible to optimize the prologue
......@@ -1413,59 +1420,30 @@ i370_function_prolog (f, frame_size)
fprintf (f, "\t.long\t%d\n", aligned_size);
/* FENT == function prologue entry */
fprintf (f, ".LFENT%03d:\n\t.balign 2\n", /* FENT%03d DS 0H */
fprintf (f, "\t.balign 2\n.LFENT%03d:\n",
function_label_index);
/* store multiple of registers 14,15,0,...12 at 12 bytes from sp */
/* store multiple registers 14,15,0,...12 at 12 bytes from sp */
fprintf (f, "\tSTM\tr14,r12,12(sp)\n");
/* r11 points to arg list in callers stackframe; was passed in r2 */
fprintf (f, "\tLR\tr11,r2\n");
/* r2 == callee stack pointer ; 76(sp) == caller top of stack */
fprintf (f, "\tL\tr2,76(,sp)\n");
/* 4(r15) == callee stack length */
fprintf (f, "\tL\tr0,4(,r15)\n");
/* r3 == saved callee stack pointer */
fprintf (f, "\tLR\tr3,sp\n");
/* add callee stack length to caller top of stack */
fprintf (f, "\tALR\tr0,r2\n");
/* 4(r15) == stackframe size */
fprintf (f, "\tSL\tsp,4(,r15)\n");
/* is there enough room for this new stack frame? */
fprintf (f, "\tCL\tr0,12(,rtca)\n");
/* if we've got room, skip next 2 insns */
fprintf (f, "\tBNH\t*+10\n");
/* branch to tca to get more stack */
fprintf (f, "\tL\tr15,116(,rtca)\n");
/* go */
fprintf (f, "\tBASR\tr14,r15\n");
/* 72(sp) is something that is propagated up from the base of the stack.
We don't use this anywhere, so we could chop this out. For the moment,
Lets keep it; it might be handy someday ... */
fprintf (f, "\tL\tr15,72(,sp)\n");
/* store the new top-of-stack at 76(callee_stack) */
fprintf (f, "\tSTM\tr15,r0,72(r2)\n");
/* store some PL/1 compatible eyecatcher ???? why bother ??? */
fprintf (f, "\tMVI\t0(r2),0x10\n");
/* r11 points to arg list in callers stackframe; was passed in r2 */
fprintf (f, "\tLR\tr11,r2\n");
/* store callee stack pointer at 8(sp) */
fprintf (f, "\tST\tr2,8(,sp)\n ");
/* store caller sp at 4(callee_sp) */
fprintf (f, "\tST\tsp,4(,r2)\n ");
/* fprintf (f, "\tST\tsp,8(,r3)\n "); wasted cycles, no one uses this ... */
/* load calle_sp into sp */
fprintf (f, "\tLR\tsp,r2\n");
/* backchain -- store caller sp at 4(callee_sp) */
fprintf (f, "\tST\tr3,4(,sp)\n ");
fprintf (f, "\t.drop\tr15\n");
/* place contents of the PSW into r3
* that is, place the address of "." into r3 */
/* Place contents of the PSW into r3
that is, place the address of "." into r3 */
fprintf (f, "\tBASR\tr%d,0\n", BASE_REGISTER);
fprintf (f, "\t.using\t.,r%d\n", BASE_REGISTER);
function_first = 1;
......
......@@ -187,6 +187,7 @@ extern int mvs_function_name_length;
#define BASE_REGISTER 3
#define PAGE_REGISTER 4
#ifdef TARGET_HLASM
/* 1 for registers that have pervasive standard uses and are not available
for the register allocator. These are registers that must have fixed,
valid values stored in them for the entire length of the subroutine call,
......@@ -249,6 +250,26 @@ extern int mvs_function_name_length;
but can be less for certain modes in special long registers.
Note that DCmode (complex double) needs two regs.
*/
#endif /* TARGET_HLASM */
/* ================= */
#ifdef TARGET_ELF_ABI
/* The Linux/ELF ABI uses the same register layout as the
* the MVS/OE version, with the following exceptions:
* -- r12 (rtca) is not used.
*/
#define FIXED_REGISTERS \
{ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0 }
/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/
#define CALL_USED_REGISTERS \
{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 }
/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19*/
#endif /* TARGET_ELF_ABI */
/* ================= */
#define HARD_REGNO_NREGS(REGNO, MODE) \
((REGNO) > 15 ? \
......@@ -327,7 +348,7 @@ extern int mvs_function_name_length;
A_t a; a.a=1; a.b=2 a.c=3;
return a;
}
In the above, the stroage for the return value is in the callers stack, and
In the above, the storage for the return value is in the callers stack, and
the R1 points at that mem location.
*/
......@@ -444,7 +465,10 @@ enum reg_class
/* Define this if pushing a word on the stack makes the stack pointer a
smaller address. */
/* ------------------------------------------------------------------- */
/* ================= */
#ifdef TARGET_HLASM
/* #define STACK_GROWS_DOWNWARD */
/* Define this if the nominal address of the stack frame is at the
......@@ -466,6 +490,29 @@ enum reg_class
/* If we generate an insn to push BYTES bytes, this says how many the stack
pointer really advances by. On the 370, we have no push instruction. */
#endif /* TARGET_HLASM */
/* ================= */
#ifdef TARGET_ELF_ABI
/* With ELF/Linux, stack is placed at large virtual addrs and grows down.
But we want the compiler to generate posistive displacements from the
stack pointer, and so we make the frame lie above the stack. */
#define STACK_GROWS_DOWNWARD
/* #define FRAME_GROWS_DOWNWARD */
/* Offset within stack frame to start allocating local variables at.
This is the offset to the BEGINNING of the first local allocated. */
#define STARTING_FRAME_OFFSET \
(STACK_POINTER_OFFSET + current_function_outgoing_args_size)
#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = STARTING_FRAME_OFFSET
#endif /* TARGET_ELF_ABI */
/* ================= */
/* #define PUSH_ROUNDING(BYTES) */
/* Accumulate the outgoing argument count so we can request the right
......@@ -529,7 +576,7 @@ enum reg_class
#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
/* The FUNCTION_VALUE macro dDefines how to find the value returned by a
/* The FUNCTION_VALUE macro defines how to find the value returned by a
function. VALTYPE is the data type of the value (as a tree).
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is NULL.
......@@ -1559,7 +1606,7 @@ enum reg_class
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
{ \
if (strlen (NAME) * 2 > mvs_function_name_length) \
if (strlen (NAME) + 1 > mvs_function_name_length) \
{ \
if (mvs_function_name) \
free (mvs_function_name); \
......@@ -1567,7 +1614,7 @@ enum reg_class
} \
if (!mvs_function_name) \
{ \
mvs_function_name_length = strlen (NAME) * 2; \
mvs_function_name_length = strlen (NAME) * 2 + 1; \
mvs_function_name = (char *) xmalloc (mvs_function_name_length); \
} \
if (!strcmp (NAME, "main")) \
......
......@@ -647,7 +647,9 @@ check_label_emit ();
else if (REG_P (operands[1]))
{
mvs_check_page (0, 4, 0);
return \"STM %1,%N1,%0\";
/* can't use stm otherwise stm r6,r7,0(r10,r13) can happen */
return \"STM %1,%N1,%0\";
/* return \"ST %1,%0\;ST %N1,4+%0\"; */
}
mvs_check_page (0, 6, 0);
return \"MVC %O0(8,%R0),%W1\";
......@@ -1825,8 +1827,6 @@ check_label_emit ();
;
; floatsidf2 instruction pattern(s).
;
; Uses the float field of the TCA.
;
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "general_operand" "=f")
......@@ -1837,7 +1837,7 @@ check_label_emit ();
check_label_emit ();
CC_STATUS_INIT;
mvs_check_page (0, 16, 8);
return \"ST %1,508(,12)\;XI 508(12),128\;LD %0,504(,12)\;SD %0,=XL8'4E00000080000000'\";
return \"ST %1,144(,13)\;XI 144(13),128\;LD %0,140(,13)\;SD %0,=XL8'4E00000080000000'\";
}"
[(set_attr "length" "16")]
)
......@@ -3021,7 +3021,7 @@ check_label_emit ();
(define_insn ""
[(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
(ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
(match_operand:SI 2 "r_or_s_operand" "g,mi")))]
(match_operand:SI 2 "r_or_s_operand" "g,Si")))]
"TARGET_CHAR_INSTRUCTIONS"
"*
{
......
......@@ -19,3 +19,10 @@ CC=c89
CLIB=-liberty
LDFLAGS=-L../libiberty
# TAR Options
# Please note that OpenEdition confuses tar and pax, and
# thus uses the non-standard options 'xpf'
TAROUTOPTS=xpf
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment