bytecode
From-SVN: r5379
This commit is contained in:
parent
86d7f2db05
commit
ca695ac93d
@ -399,6 +399,9 @@ CPLUS_OBJS = cp-parse.o cp-decl.o cp-decl2.o \
|
||||
cp-expr.o cp-pt.o cp-edsel.o cp-xref.o \
|
||||
$(CPLUS_INPUT) cp-spew.o c-common.o
|
||||
|
||||
# Files specific to the C interpreter bytecode compiler(s).
|
||||
BC_OBJS = bc-emit.o bc-optab.o
|
||||
|
||||
# Language-independent object files.
|
||||
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
|
||||
function.o stmt.o expr.o calls.o expmed.o explow.o optabs.o varasm.o \
|
||||
@ -461,6 +464,7 @@ CONFIG_H =
|
||||
RTL_H = rtl.h rtl.def machmode.h machmode.def
|
||||
TREE_H = tree.h real.h tree.def machmode.h machmode.def
|
||||
CPLUS_TREE_H = $(TREE_H) cp-tree.h cp-tree.def
|
||||
BYTECODE_H = bytecode.h bc-emit.h bc-optab.h
|
||||
|
||||
# Avoid a lot of time thinking about remaking Makefile.in and *.def.
|
||||
.SUFFIXES: .in .def
|
||||
@ -484,7 +488,7 @@ for-bootstrap: start.encap $(LIBGCC)
|
||||
rest.encap: $(LIBGCC) stmp-headers $(STMP_FIXPROTO) $(EXTRA_PARTS)
|
||||
# This is what is made with the host's compiler
|
||||
# whether making a cross compiler or not.
|
||||
native: config.status cpp $(LANGUAGES) $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2)
|
||||
native: bytecode config.status cpp $(LANGUAGES) $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2)
|
||||
|
||||
# Define the names for selecting languages in LANGUAGES.
|
||||
C c: cc1
|
||||
@ -545,14 +549,14 @@ g++-cross: $(srcdir)/g++.c
|
||||
$(CC) $(ALL_CFLAGS) $(INCLUDES) $(LDFLAGS) -o g++-cross \
|
||||
-DGCC_NAME=\"$(target)-gcc\" $(srcdir)/g++.c version.o $(LIBS)
|
||||
|
||||
cc1:$(P) $(C_OBJS) $(OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1 $(C_OBJS) $(OBJS) $(LIBS)
|
||||
cc1:$(P) $(C_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1 $(C_OBJS) $(OBJS) $(BC_OBJS) $(LIBS)
|
||||
|
||||
cc1plus:$(P) $(CPLUS_OBJS) $(OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1plus $(CPLUS_OBJS) $(OBJS) $(LIBS)
|
||||
cc1plus:$(P) $(CPLUS_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1plus $(CPLUS_OBJS) $(BC_OBJS) $(OBJS) $(LIBS)
|
||||
|
||||
cc1obj:$(P) $(OBJC_OBJS) $(OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1obj $(OBJC_OBJS) $(OBJS) $(LIBS)
|
||||
cc1obj:$(P) $(OBJC_OBJS) $(OBJS) $(BC_OBJS) $(LIBDEPS)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cc1obj $(OBJC_OBJS) $(OBJS) $(BC_OBJS) $(LIBS)
|
||||
|
||||
# Copy float.h from its source.
|
||||
gfloat.h: $(FLOAT_H)
|
||||
@ -1247,6 +1251,63 @@ $(HOST_PREFIX_1)malloc.o: malloc.c
|
||||
$(HOST_PREFIX_1):
|
||||
touch $(HOST_PREFIX_1)
|
||||
|
||||
# Remake bytecode files.
|
||||
# BI_ALL=bi-run.o
|
||||
BI_ALL=
|
||||
BC_ALL=bc-opname.h bc-opcode.h bc-arity.h
|
||||
BI_OBJ=bi-parser.o bi-lexer.o bi-reverse.o
|
||||
|
||||
|
||||
bc-emit.o : bc-emit.c $(CONFIG_H) $(BYTECODE_H)
|
||||
bc-optab.o : bc-optab.c bc-typecd.def $(CONFIG_H) $(BYTECODE_H)
|
||||
|
||||
|
||||
bytecode: $(BI_ALL) $(BC_ALL)
|
||||
|
||||
bi-arity: bi-arity.o
|
||||
bi-opcode: bi-opcode.o
|
||||
bi-opname: bi-opname.o
|
||||
bi-unparse: bi-unparse.o
|
||||
bi-lexer: bi-lexer.o
|
||||
|
||||
bi-arity bi-opcode bi-opname bi-unparse bi-lexer: $(BI_OBJ)
|
||||
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $^ $(LEXLIB)
|
||||
|
||||
bi-run.o: $(srcdir)/bi-run.c $(srcdir)/bi-run.h $(srcdir)/bc-typecd.h bc-opname.h bc-arity.h bc-opcode.h
|
||||
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $<
|
||||
|
||||
bi-parser.c: $(srcdir)/bi-parser.y $(srcdir)/bi-parser.h
|
||||
|
||||
bi-parser.o: $(srcdir)/bi-parser.c $(srcdir)/bi-defs.h
|
||||
$(CC) $(CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $<
|
||||
|
||||
bi-lexer.c: $(srcdir)/bi-lexer.l $(srcdir)/bi-parser.h
|
||||
|
||||
bi-lexer.o: bi-lexer.c bi-parser.h
|
||||
$(CC) $(CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $<
|
||||
|
||||
bc-arity.h: $(srcdir)/bytecode.def bi-arity
|
||||
-rm -f $@
|
||||
bi-arity <$< >$@
|
||||
|
||||
bc-opcode.h: $(srcdir)/bytecode.def bi-opcode
|
||||
-rm -f $@
|
||||
bi-opcode <$< >$@
|
||||
|
||||
bc-opname.h: $(srcdir)/bytecode.def bi-opname
|
||||
-rm -f $@
|
||||
bi-opname <$< >$@
|
||||
|
||||
bytecode.mostlyclean:
|
||||
-rm -f bc-arity.h bc-opcode.h bc-opname.h
|
||||
|
||||
bytecode.distclean bytecode.clean: bytecode.mostlyclean
|
||||
-rm -f bi-arity bi-opcode bi-opname bi-unparse bi-lexer
|
||||
|
||||
bytecode.realclean: bytecode.clean
|
||||
-rm -f bi-parser.c bi-lexer.c bi-parser.h
|
||||
|
||||
|
||||
# Remake cpp and protoize.
|
||||
|
||||
# Making the preprocessor
|
||||
@ -1507,7 +1568,7 @@ $(srcdir)/INSTALL: install1.texi install.texi
|
||||
# `realclean' also deletes everything that could be regenerated automatically.
|
||||
|
||||
|
||||
mostlyclean:
|
||||
mostlyclean: bytecode.mostlyclean
|
||||
-rm -f $(STAGESTUFF)
|
||||
# Clean the objc subdir if we created one.
|
||||
if [ -d objc ]; then \
|
||||
@ -1545,7 +1606,7 @@ mostlyclean:
|
||||
|
||||
# Delete all files made by compilation
|
||||
# that don't exist in the distribution.
|
||||
clean: mostlyclean
|
||||
clean: mostlyclean bytecode.clean
|
||||
# It may not be quite desirable to delete unprotoize.c here,
|
||||
# but the spec for `make clean' requires it.
|
||||
# Using unprotoize.c is not quite right in the first place,
|
||||
@ -1557,7 +1618,7 @@ clean: mostlyclean
|
||||
|
||||
# Delete all files that users would normally create
|
||||
# while building and installing GCC.
|
||||
distclean: clean
|
||||
distclean: clean bytecode.distclean
|
||||
-rm -f tm.h aux-output.c config.h md config.status tconfig.h hconfig.h
|
||||
-rm -f Makefile *.oaux
|
||||
-rm -fr stage1 stage2 stage3 stage4
|
||||
@ -1581,7 +1642,7 @@ extraclean: distclean
|
||||
|
||||
# Get rid of every file that's generated from some other file.
|
||||
# Most of these files ARE PRESENT in the GCC distribution.
|
||||
realclean: distclean
|
||||
realclean: distclean bytecode.realclean
|
||||
-rm -f c-parse.y objc-parse.y
|
||||
-rm -f cp-parse.c cp-parse.h cp-parse.output
|
||||
-rm -f objc-parse.c objc-parse.output
|
||||
|
@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
#include "tree.h"
|
||||
#include "function.h"
|
||||
|
||||
#ifdef HANDLE_SYSV_PRAGMA
|
||||
|
||||
@ -45,20 +46,7 @@ handle_pragma_token (string, token)
|
||||
char *string;
|
||||
tree token;
|
||||
{
|
||||
static enum pragma_state
|
||||
{
|
||||
ps_start,
|
||||
ps_done,
|
||||
ps_bad,
|
||||
ps_weak,
|
||||
ps_name,
|
||||
ps_equals,
|
||||
ps_value,
|
||||
ps_pack,
|
||||
ps_left,
|
||||
ps_align,
|
||||
ps_right
|
||||
} state = ps_start, type;
|
||||
static enum pragma_state state = ps_start, type;
|
||||
static char *name;
|
||||
static char *value;
|
||||
static int align;
|
||||
@ -76,24 +64,8 @@ handle_pragma_token (string, token)
|
||||
{
|
||||
#ifdef HANDLE_PRAGMA_WEAK
|
||||
if (HANDLE_PRAGMA_WEAK)
|
||||
{
|
||||
if (state == ps_name || state == ps_value)
|
||||
{
|
||||
fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
fputc ('\n', asm_out_file);
|
||||
if (state == ps_value)
|
||||
{
|
||||
fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
fputc (',', asm_out_file);
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, value);
|
||||
fputc ('\n', asm_out_file);
|
||||
}
|
||||
}
|
||||
else if (! (state == ps_done || state == ps_start))
|
||||
warning ("malformed `#pragma weak'");
|
||||
}
|
||||
handle_pragma_weak (state, asm_out_file, name, value);
|
||||
|
||||
#endif /* HANDLE_PRAMA_WEAK */
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,29 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "regs.h"
|
||||
#include "insn-config.h"
|
||||
#include "real.h"
|
||||
#include "obstack.h"
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "machmode.h"
|
||||
#include "bc-opcode.h"
|
||||
#include "bc-typecd.h"
|
||||
#include "bc-optab.h"
|
||||
#include "bc-emit.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Opcode names */
|
||||
#ifdef BCDEBUG_PRINT_CODE
|
||||
char *opcode_name[] =
|
||||
{
|
||||
#include "bc-opname.h"
|
||||
|
||||
"***END***"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
|
||||
After rtl generation, it is 1 plus the largest register number used. */
|
||||
|
||||
@ -203,6 +224,11 @@ extern int emit_lineno;
|
||||
rtx change_address ();
|
||||
void init_emit ();
|
||||
|
||||
extern struct obstack *rtl_obstack;
|
||||
|
||||
extern int stack_depth;
|
||||
extern int max_stack_depth;
|
||||
|
||||
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
|
||||
**
|
||||
** This routine generates an RTX of the size specified by
|
||||
@ -1216,8 +1242,12 @@ change_address (memref, mode, addr)
|
||||
rtx
|
||||
gen_label_rtx ()
|
||||
{
|
||||
register rtx label = gen_rtx (CODE_LABEL, VOIDmode, 0, 0, 0,
|
||||
label_num++, NULL_PTR);
|
||||
register rtx label;
|
||||
|
||||
label = output_bytecode
|
||||
? bc_gen_rtx (0, 0, bc_get_bytecode_label ())
|
||||
: gen_rtx (CODE_LABEL, VOIDmode, 0, 0, 0, label_num++, NULL_PTR);
|
||||
|
||||
LABEL_NUSES (label) = 0;
|
||||
return label;
|
||||
}
|
||||
@ -2559,6 +2589,13 @@ emit_line_note (file, line)
|
||||
char *file;
|
||||
int line;
|
||||
{
|
||||
if (output_bytecode)
|
||||
{
|
||||
/* FIXME: for now we do nothing, but eventually we will have to deal with
|
||||
debugging information. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
emit_filename = file;
|
||||
emit_lineno = line;
|
||||
|
||||
|
1308
gcc/expr.c
1308
gcc/expr.c
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "integrate.h"
|
||||
#include "real.h"
|
||||
#include "function.h"
|
||||
#include "bytecode.h"
|
||||
|
||||
#include "obstack.h"
|
||||
#define obstack_chunk_alloc xmalloc
|
||||
@ -2850,9 +2851,16 @@ void
|
||||
output_inline_function (fndecl)
|
||||
tree fndecl;
|
||||
{
|
||||
rtx head = DECL_SAVED_INSNS (fndecl);
|
||||
rtx head;
|
||||
rtx last;
|
||||
|
||||
if (output_bytecode)
|
||||
{
|
||||
warning ("`inline' ignored for bytecode output");
|
||||
return;
|
||||
}
|
||||
|
||||
head = DECL_SAVED_INSNS (fndecl);
|
||||
current_function_decl = fndecl;
|
||||
|
||||
/* This call is only used to initialize global variables. */
|
||||
|
@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "recog.h"
|
||||
#include "reload.h"
|
||||
#include "real.h"
|
||||
#include "bytecode.h"
|
||||
|
||||
#ifndef REGISTER_MOVE_COST
|
||||
#define REGISTER_MOVE_COST(x, y) 2
|
||||
@ -413,6 +414,13 @@ fix_register (name, fixed, call_used)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (output_bytecode)
|
||||
{
|
||||
warning ("request to mark `%s' as %s ignored by bytecode compiler",
|
||||
name, call_used ? "call-used" : "fixed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Decode the name and update the primary form of
|
||||
the register info. */
|
||||
|
||||
|
17
gcc/rtl.h
17
gcc/rtl.h
@ -139,6 +139,22 @@ typedef struct rtx_def
|
||||
The number of operands and their types are controlled
|
||||
by the `code' field, according to rtl.def. */
|
||||
rtunion fld[1];
|
||||
|
||||
/* The rest is used instead of the above if bytecode is being output */
|
||||
|
||||
/* For static or external objects. */
|
||||
char *label;
|
||||
|
||||
/* From the named label, or the local variable pointer or the
|
||||
argument pointer, depending on context. */
|
||||
|
||||
int offset;
|
||||
|
||||
/* For goto labels inside bytecode functions. */
|
||||
struct bc_label *bc_label;
|
||||
|
||||
/* A unique identifier */
|
||||
int uid;
|
||||
} *rtx;
|
||||
|
||||
/* Add prototype support. */
|
||||
@ -640,6 +656,7 @@ extern rtx gen_rtx PROTO((enum rtx_code, enum machine_mode, ...));
|
||||
extern rtvec gen_rtvec PROTO((int, ...));
|
||||
|
||||
#else
|
||||
extern rtx bc_gen_rtx ();
|
||||
extern rtx gen_rtx ();
|
||||
extern rtvec gen_rtvec ();
|
||||
#endif
|
||||
|
930
gcc/stmt.c
930
gcc/stmt.c
File diff suppressed because it is too large
Load Diff
153
gcc/toplev.c
153
gcc/toplev.c
@ -57,6 +57,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#ifdef XCOFF_DEBUGGING_INFO
|
||||
#include "xcoffout.h"
|
||||
#endif
|
||||
|
||||
#include "bytecode.h"
|
||||
#include "bc-emit.h"
|
||||
|
||||
#ifdef VMS
|
||||
/* The extra parameters substantially improve the I/O performance. */
|
||||
@ -211,6 +214,9 @@ int errorcount = 0;
|
||||
int warningcount = 0;
|
||||
int sorrycount = 0;
|
||||
|
||||
/* Flag to output bytecode instead of native assembler */
|
||||
int output_bytecode = 0;
|
||||
|
||||
/* Pointer to function to compute the name to use to print a declaration. */
|
||||
|
||||
char *(*decl_printable_name) ();
|
||||
@ -515,6 +521,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
|
||||
{"inhibit-size-directive", &flag_inhibit_size_directive, 1},
|
||||
{"verbose-asm", &flag_verbose_asm, 1},
|
||||
{"gnu-linker", &flag_gnu_linker, 1}
|
||||
{"bytecode", &output_bytecode, 1}
|
||||
};
|
||||
|
||||
/* Table of language-specific options. */
|
||||
@ -885,11 +892,14 @@ void
|
||||
fatal_insn_not_found (insn)
|
||||
rtx insn;
|
||||
{
|
||||
if (INSN_CODE (insn) < 0)
|
||||
error ("internal error--unrecognizable insn:", 0);
|
||||
else
|
||||
error ("internal error--insn does not satisfy its constraints:", 0);
|
||||
debug_rtx (insn);
|
||||
if (!output_bytecode)
|
||||
{
|
||||
if (INSN_CODE (insn) < 0)
|
||||
error ("internal error--unrecognizable insn:", 0);
|
||||
else
|
||||
error ("internal error--insn does not satisfy its constraints:", 0);
|
||||
debug_rtx (insn);
|
||||
}
|
||||
if (asm_out_file)
|
||||
fflush (asm_out_file);
|
||||
if (aux_info_file)
|
||||
@ -1585,6 +1595,8 @@ compile_file (name)
|
||||
init_obstacks ();
|
||||
init_tree_codes ();
|
||||
init_lex ();
|
||||
/* Some of these really don't need to be called when generating bytecode,
|
||||
but the options would have to be parsed first to know that. -bson */
|
||||
init_rtl ();
|
||||
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|
||||
|| debug_info_level == DINFO_LEVEL_VERBOSE);
|
||||
@ -1813,34 +1825,51 @@ compile_file (name)
|
||||
input_file_stack->next = 0;
|
||||
input_file_stack->name = input_filename;
|
||||
|
||||
ASM_FILE_START (asm_out_file);
|
||||
if (!output_bytecode)
|
||||
{
|
||||
ASM_FILE_START (asm_out_file);
|
||||
}
|
||||
|
||||
/* Output something to inform GDB that this compilation was by GCC. */
|
||||
/* Output something to inform GDB that this compilation was by GCC. Also
|
||||
serves to tell GDB file consists of bytecodes. */
|
||||
if (output_bytecode)
|
||||
fprintf (asm_out_file, "bc_gcc2_compiled.:\n");
|
||||
else
|
||||
{
|
||||
#ifndef ASM_IDENTIFY_GCC
|
||||
fprintf (asm_out_file, "gcc2_compiled.:\n");
|
||||
fprintf (asm_out_file, "gcc2_compiled.:\n");
|
||||
#else
|
||||
ASM_IDENTIFY_GCC (asm_out_file);
|
||||
ASM_IDENTIFY_GCC (asm_out_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Output something to identify which front-end produced this file. */
|
||||
#ifdef ASM_IDENTIFY_LANGUAGE
|
||||
ASM_IDENTIFY_LANGUAGE (asm_out_file);
|
||||
#endif
|
||||
|
||||
/* ??? Note: There used to be a conditional here
|
||||
to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
|
||||
This was to guarantee separation between gcc_compiled. and
|
||||
the first function, for the sake of dbx on Suns.
|
||||
However, having the extra zero here confused the Emacs
|
||||
code for unexec, and might confuse other programs too.
|
||||
Therefore, I took out that change.
|
||||
In future versions we should find another way to solve
|
||||
that dbx problem. -- rms, 23 May 93. */
|
||||
|
||||
/* Don't let the first function fall at the same address
|
||||
as gcc_compiled., if profiling. */
|
||||
if (profile_flag || profile_block_flag)
|
||||
assemble_zeros (UNITS_PER_WORD);
|
||||
if (output_bytecode)
|
||||
{
|
||||
if (profile_flag || profile_block_flag)
|
||||
error ("profiling not supported in bytecode compilation");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ??? Note: There used to be a conditional here
|
||||
to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
|
||||
This was to guarantee separation between gcc_compiled. and
|
||||
the first function, for the sake of dbx on Suns.
|
||||
However, having the extra zero here confused the Emacs
|
||||
code for unexec, and might confuse other programs too.
|
||||
Therefore, I took out that change.
|
||||
In future versions we should find another way to solve
|
||||
that dbx problem. -- rms, 23 May 93. */
|
||||
|
||||
/* Don't let the first function fall at the same address
|
||||
as gcc_compiled., if profiling. */
|
||||
if (profile_flag || profile_block_flag)
|
||||
assemble_zeros (UNITS_PER_WORD);
|
||||
}
|
||||
|
||||
/* If dbx symbol table desired, initialize writing it
|
||||
and output the predefined types. */
|
||||
@ -1861,7 +1890,8 @@ compile_file (name)
|
||||
|
||||
/* Initialize yet another pass. */
|
||||
|
||||
init_final (main_input_filename);
|
||||
if (!output_bytecode)
|
||||
init_final (main_input_filename);
|
||||
|
||||
start_time = get_run_time ();
|
||||
|
||||
@ -2031,11 +2061,14 @@ compile_file (name)
|
||||
|
||||
/* Output some stuff at end of file if nec. */
|
||||
|
||||
end_final (main_input_filename);
|
||||
if (!output_bytecode)
|
||||
{
|
||||
end_final (main_input_filename);
|
||||
|
||||
#ifdef ASM_FILE_END
|
||||
ASM_FILE_END (asm_out_file);
|
||||
ASM_FILE_END (asm_out_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
after_finish_compilation:
|
||||
|
||||
@ -2113,24 +2146,28 @@ compile_file (name)
|
||||
{
|
||||
fprintf (stderr,"\n");
|
||||
print_time ("parse", parse_time);
|
||||
print_time ("integration", integration_time);
|
||||
print_time ("jump", jump_time);
|
||||
print_time ("cse", cse_time);
|
||||
print_time ("loop", loop_time);
|
||||
print_time ("cse2", cse2_time);
|
||||
print_time ("flow", flow_time);
|
||||
print_time ("combine", combine_time);
|
||||
print_time ("sched", sched_time);
|
||||
print_time ("local-alloc", local_alloc_time);
|
||||
print_time ("global-alloc", global_alloc_time);
|
||||
print_time ("sched2", sched2_time);
|
||||
print_time ("dbranch", dbr_sched_time);
|
||||
print_time ("shorten-branch", shorten_branch_time);
|
||||
print_time ("stack-reg", stack_reg_time);
|
||||
print_time ("final", final_time);
|
||||
print_time ("varconst", varconst_time);
|
||||
print_time ("symout", symout_time);
|
||||
print_time ("dump", dump_time);
|
||||
|
||||
if (!output_bytecode)
|
||||
{
|
||||
print_time ("integration", integration_time);
|
||||
print_time ("jump", jump_time);
|
||||
print_time ("cse", cse_time);
|
||||
print_time ("loop", loop_time);
|
||||
print_time ("cse2", cse2_time);
|
||||
print_time ("flow", flow_time);
|
||||
print_time ("combine", combine_time);
|
||||
print_time ("sched", sched_time);
|
||||
print_time ("local-alloc", local_alloc_time);
|
||||
print_time ("global-alloc", global_alloc_time);
|
||||
print_time ("sched2", sched2_time);
|
||||
print_time ("dbranch", dbr_sched_time);
|
||||
print_time ("shorten-branch", shorten_branch_time);
|
||||
print_time ("stack-reg", stack_reg_time);
|
||||
print_time ("final", final_time);
|
||||
print_time ("varconst", varconst_time);
|
||||
print_time ("symout", symout_time);
|
||||
print_time ("dump", dump_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2236,6 +2273,9 @@ rest_of_compilation (decl)
|
||||
tree saved_arguments = 0;
|
||||
int failure = 0;
|
||||
|
||||
if (output_bytecode)
|
||||
return;
|
||||
|
||||
/* If we are reconsidering an inline function
|
||||
at the end of compilation, skip the stuff for making it inline. */
|
||||
|
||||
@ -3166,7 +3206,12 @@ main (argc, argv, envp)
|
||||
error ("Invalid option `%s'", argv[i]);
|
||||
}
|
||||
else if (!strcmp (str, "p"))
|
||||
profile_flag = 1;
|
||||
{
|
||||
if (!output_bytecode)
|
||||
profile_flag = 1;
|
||||
else
|
||||
error ("profiling not supported in bytecode compilation");
|
||||
}
|
||||
else if (!strcmp (str, "a"))
|
||||
{
|
||||
#if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
|
||||
@ -3325,6 +3370,18 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
|
||||
filename = argv[i];
|
||||
}
|
||||
|
||||
/* Initialize for bytecode output. A good idea to do this as soon as
|
||||
possible after the "-f" options have been parsed. */
|
||||
if (output_bytecode)
|
||||
{
|
||||
#ifndef TARGET_SUPPORTS_BYTECODE
|
||||
/* Just die with a fatal error if not supported */
|
||||
fatal ("-fbytecode can not be used for this target");
|
||||
#else
|
||||
bc_initialize ();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (optimize == 0)
|
||||
{
|
||||
/* Inlining does not work if not optimizing,
|
||||
@ -3398,10 +3455,14 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
|
||||
}
|
||||
|
||||
/* Now that register usage is specified, convert it to HARD_REG_SETs. */
|
||||
init_reg_sets_1 ();
|
||||
if (!output_bytecode)
|
||||
init_reg_sets_1 ();
|
||||
|
||||
compile_file (filename);
|
||||
|
||||
if (output_bytecode)
|
||||
bc_write_file (stdout);
|
||||
|
||||
#ifndef OS2
|
||||
#ifndef VMS
|
||||
if (flag_print_mem)
|
||||
|
562
gcc/varasm.c
562
gcc/varasm.c
@ -38,6 +38,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "regs.h"
|
||||
#include "defaults.h"
|
||||
#include "real.h"
|
||||
#include "bytecode.h"
|
||||
|
||||
#include "obstack.h"
|
||||
|
||||
@ -96,9 +97,11 @@ void assemble_name ();
|
||||
int output_addressed_constants ();
|
||||
void output_constant ();
|
||||
void output_constructor ();
|
||||
void output_byte_asm ();
|
||||
void text_section ();
|
||||
void readonly_data_section ();
|
||||
void data_section ();
|
||||
static void bc_assemble_integer ();
|
||||
|
||||
#ifdef EXTRA_SECTIONS
|
||||
static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
|
||||
@ -120,7 +123,11 @@ text_section ()
|
||||
{
|
||||
if (in_section != in_text)
|
||||
{
|
||||
fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
|
||||
if (output_bytecode)
|
||||
bc_text ();
|
||||
else
|
||||
fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
|
||||
|
||||
in_section = in_text;
|
||||
}
|
||||
}
|
||||
@ -132,16 +139,21 @@ data_section ()
|
||||
{
|
||||
if (in_section != in_data)
|
||||
{
|
||||
if (flag_shared_data)
|
||||
{
|
||||
#ifdef SHARED_SECTION_ASM_OP
|
||||
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
|
||||
#else
|
||||
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
|
||||
#endif
|
||||
}
|
||||
if (output_bytecode)
|
||||
bc_data ();
|
||||
else
|
||||
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
|
||||
{
|
||||
if (flag_shared_data)
|
||||
{
|
||||
#ifdef SHARED_SECTION_ASM_OP
|
||||
fprintf (asm_out_file, "%s\n", SHARED_SECTION_ASM_OP);
|
||||
#else
|
||||
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
|
||||
}
|
||||
|
||||
in_section = in_data;
|
||||
}
|
||||
@ -178,6 +190,16 @@ make_function_rtl (decl)
|
||||
{
|
||||
char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
|
||||
if (output_bytecode)
|
||||
{
|
||||
if (DECL_RTL (decl) == 0)
|
||||
DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
|
||||
|
||||
/* Record that at least one function has been defined. */
|
||||
function_defined = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Rename a nested function to avoid conflicts. */
|
||||
if (decl_function_context (decl) != 0
|
||||
&& DECL_INITIAL (decl) != 0
|
||||
@ -211,6 +233,48 @@ make_function_rtl (decl)
|
||||
function_defined = 1;
|
||||
}
|
||||
|
||||
/* Create the DECL_RTL for a declaration for a static or external
|
||||
variable or static or external function.
|
||||
ASMSPEC, if not 0, is the string which the user specified
|
||||
as the assembler symbol name.
|
||||
TOP_LEVEL is nonzero if this is a file-scope variable.
|
||||
This is never called for PARM_DECLs. */
|
||||
void
|
||||
bc_make_decl_rtl (decl, asmspec, top_level)
|
||||
tree decl;
|
||||
char *asmspec;
|
||||
int top_level;
|
||||
{
|
||||
register char *name = TREE_STRING_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
|
||||
if (DECL_RTL (decl) == 0)
|
||||
{
|
||||
/* Print an error message for register variables. */
|
||||
if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
|
||||
error ("function declared `register'");
|
||||
else if (DECL_REGISTER (decl))
|
||||
error ("global register variables not supported in the interpreter");
|
||||
|
||||
/* Handle ordinary static variables and functions. */
|
||||
if (DECL_RTL (decl) == 0)
|
||||
{
|
||||
/* Can't use just the variable's own name for a variable
|
||||
whose scope is less than the whole file.
|
||||
Concatenate a distinguishing number. */
|
||||
if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
|
||||
{
|
||||
char *label;
|
||||
|
||||
ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
|
||||
name = obstack_copy0 (saveable_obstack, label, strlen (label));
|
||||
var_labelno++;
|
||||
}
|
||||
|
||||
DECL_RTL (decl) = bc_gen_rtx (name, 0, (struct bc_label *) 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Given NAME, a putative register name, discard any customary prefixes. */
|
||||
|
||||
static char *
|
||||
@ -301,7 +365,15 @@ make_decl_rtl (decl, asmspec, top_level)
|
||||
int top_level;
|
||||
{
|
||||
register char *name;
|
||||
int reg_number = decode_reg_name (asmspec);
|
||||
int reg_number;
|
||||
|
||||
if (output_bytecode)
|
||||
{
|
||||
bc_make_decl_rtl (decl, asmspec, top_level);
|
||||
return;
|
||||
}
|
||||
|
||||
reg_number = decode_reg_name (asmspec);
|
||||
|
||||
if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)
|
||||
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
@ -465,6 +537,12 @@ void
|
||||
assemble_asm (string)
|
||||
tree string;
|
||||
{
|
||||
if (output_bytecode)
|
||||
{
|
||||
error ("asm statements not allowed in interpreter");
|
||||
return;
|
||||
}
|
||||
|
||||
app_enable ();
|
||||
|
||||
if (TREE_CODE (string) == ADDR_EXPR)
|
||||
@ -576,7 +654,12 @@ assemble_start_function (decl, fnname)
|
||||
/* Tell assembler to move to target machine's alignment for functions. */
|
||||
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
|
||||
if (align > 0)
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, align);
|
||||
{
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_ALIGN (asm_out_file, align);
|
||||
else
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, align);
|
||||
}
|
||||
|
||||
#ifdef ASM_OUTPUT_FUNCTION_PREFIX
|
||||
ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname);
|
||||
@ -600,7 +683,10 @@ assemble_start_function (decl, fnname)
|
||||
{
|
||||
if (!first_global_object_name)
|
||||
STRIP_NAME_ENCODING (first_global_object_name, fnname);
|
||||
ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
|
||||
if (output_bytecode)
|
||||
BC_GLOBALIZE_LABEL (asm_out_file, fnname);
|
||||
else
|
||||
ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
|
||||
}
|
||||
|
||||
/* Do any machine/system dependent processing of the function name */
|
||||
@ -608,7 +694,10 @@ assemble_start_function (decl, fnname)
|
||||
ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
|
||||
#else
|
||||
/* Standard thing is just output label for the function. */
|
||||
ASM_OUTPUT_LABEL (asm_out_file, fnname);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABEL (asm_out_file, fnname);
|
||||
else
|
||||
ASM_OUTPUT_LABEL (asm_out_file, fnname);
|
||||
#endif /* ASM_DECLARE_FUNCTION_NAME */
|
||||
}
|
||||
|
||||
@ -631,6 +720,12 @@ void
|
||||
assemble_zeros (size)
|
||||
int size;
|
||||
{
|
||||
if (output_bytecode)
|
||||
{
|
||||
bc_emit_const_skip (size);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ASM_NO_SKIP_IN_TEXT
|
||||
/* The `space' pseudo in the text section outputs nop insns rather than 0s,
|
||||
so we must output 0s explicitly in the text section. */
|
||||
@ -664,7 +759,12 @@ assemble_zeros (size)
|
||||
else
|
||||
#endif
|
||||
if (size > 0)
|
||||
ASM_OUTPUT_SKIP (asm_out_file, size);
|
||||
{
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_SKIP (asm_out_file, size);
|
||||
else
|
||||
ASM_OUTPUT_SKIP (asm_out_file, size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */
|
||||
@ -688,6 +788,12 @@ assemble_string (p, size)
|
||||
int pos = 0;
|
||||
int maximum = 2000;
|
||||
|
||||
if (output_bytecode)
|
||||
{
|
||||
bc_emit (p, size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the string is very long, split it up. */
|
||||
|
||||
while (pos < size)
|
||||
@ -696,7 +802,10 @@ assemble_string (p, size)
|
||||
if (thissize > maximum)
|
||||
thissize = maximum;
|
||||
|
||||
ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_ASCII (asm_out_file, p, thissize);
|
||||
else
|
||||
ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
|
||||
|
||||
pos += thissize;
|
||||
p += thissize;
|
||||
@ -725,6 +834,9 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
|
||||
int reloc = 0;
|
||||
enum in_section saved_in_section;
|
||||
|
||||
if (output_bytecode)
|
||||
return;
|
||||
|
||||
if (GET_CODE (DECL_RTL (decl)) == REG)
|
||||
{
|
||||
/* Do output symbol info for global register variables, but do nothing
|
||||
@ -734,19 +846,22 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
|
||||
return;
|
||||
TREE_ASM_WRITTEN (decl) = 1;
|
||||
|
||||
if (!output_bytecode)
|
||||
{
|
||||
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
|
||||
/* File-scope global variables are output here. */
|
||||
if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
|
||||
&& top_level)
|
||||
dbxout_symbol (decl, 0);
|
||||
/* File-scope global variables are output here. */
|
||||
if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
|
||||
&& top_level)
|
||||
dbxout_symbol (decl, 0);
|
||||
#endif
|
||||
#ifdef SDB_DEBUGGING_INFO
|
||||
if (write_symbols == SDB_DEBUG && top_level
|
||||
/* Leave initialized global vars for end of compilation;
|
||||
see comment in compile_file. */
|
||||
&& (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
|
||||
sdbout_symbol (decl, 0);
|
||||
if (write_symbols == SDB_DEBUG && top_level
|
||||
/* Leave initialized global vars for end of compilation;
|
||||
see comment in compile_file. */
|
||||
&& (TREE_PUBLIC (decl) == 0 || DECL_INITIAL (decl) == 0))
|
||||
sdbout_symbol (decl, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Don't output any DWARF debugging information for variables here.
|
||||
In the case of local variables, the information for them is output
|
||||
@ -880,12 +995,17 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
|
||||
ASM_OUTPUT_SHARED_COMMON (asm_out_file, name, size, rounded);
|
||||
else
|
||||
#endif
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_COMMON (asm_out_file, name, size, rounded);
|
||||
else
|
||||
{
|
||||
#ifdef ASM_OUTPUT_ALIGNED_COMMON
|
||||
ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
|
||||
DECL_ALIGN (decl));
|
||||
ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
|
||||
DECL_ALIGN (decl));
|
||||
#else
|
||||
ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
|
||||
ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -894,12 +1014,17 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
|
||||
ASM_OUTPUT_SHARED_LOCAL (asm_out_file, name, size, rounded);
|
||||
else
|
||||
#endif
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
else
|
||||
{
|
||||
#ifdef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
|
||||
DECL_ALIGN (decl));
|
||||
ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
|
||||
DECL_ALIGN (decl));
|
||||
#else
|
||||
ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
@ -1017,14 +1142,22 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
|
||||
DECL_ALIGN (decl) = align;
|
||||
|
||||
if (align > BITS_PER_UNIT)
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
{
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
else
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
}
|
||||
|
||||
/* Do any machine/system dependent processing of the object. */
|
||||
#ifdef ASM_DECLARE_OBJECT_NAME
|
||||
ASM_DECLARE_OBJECT_NAME (asm_out_file, name, decl);
|
||||
#else
|
||||
/* Standard thing is just output label for the object. */
|
||||
ASM_OUTPUT_LABEL (asm_out_file, name);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABEL (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABEL (asm_out_file, name);
|
||||
#endif /* ASM_DECLARE_OBJECT_NAME */
|
||||
|
||||
if (!dont_output_data)
|
||||
@ -1110,6 +1243,55 @@ contains_pointers_p (type)
|
||||
}
|
||||
}
|
||||
|
||||
/* Output text storage for constructor CONSTR. Returns rtx of
|
||||
storage. */
|
||||
|
||||
rtx
|
||||
bc_output_constructor (constr)
|
||||
tree constr;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Must always be a literal; non-literal constructors are handled
|
||||
differently. */
|
||||
|
||||
if (!TREE_CONSTANT (constr))
|
||||
abort ();
|
||||
|
||||
/* Always const */
|
||||
text_section ();
|
||||
|
||||
/* Align */
|
||||
for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++);
|
||||
if (i > 0)
|
||||
BC_OUTPUT_ALIGN (asm_out_file, i);
|
||||
|
||||
/* Output data */
|
||||
output_constant (constr, int_size_in_bytes (TREE_TYPE (constr)));
|
||||
}
|
||||
|
||||
|
||||
/* Create storage for constructor CONSTR. */
|
||||
|
||||
void
|
||||
bc_output_data_constructor (constr)
|
||||
tree constr;
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Put in data section */
|
||||
data_section ();
|
||||
|
||||
/* Align */
|
||||
for (i = 0; TYPE_ALIGN (constr) >= BITS_PER_UNIT << (i + 1); i++);
|
||||
if (i > 0)
|
||||
BC_OUTPUT_ALIGN (asm_out_file, i);
|
||||
|
||||
/* The constructor is filled in at runtime. */
|
||||
BC_OUTPUT_SKIP (asm_out_file, int_size_in_bytes (TREE_TYPE (constr)));
|
||||
}
|
||||
|
||||
|
||||
/* Output something to declare an external symbol to the assembler.
|
||||
(Most assemblers don't need this, so we normally output nothing.)
|
||||
Do nothing if DECL is not external. */
|
||||
@ -1118,6 +1300,9 @@ void
|
||||
assemble_external (decl)
|
||||
tree decl;
|
||||
{
|
||||
if (output_bytecode)
|
||||
return;
|
||||
|
||||
#ifdef ASM_OUTPUT_EXTERNAL
|
||||
if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
|
||||
&& DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
|
||||
@ -1142,11 +1327,14 @@ assemble_external_libcall (fun)
|
||||
rtx fun;
|
||||
{
|
||||
#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
|
||||
/* Declare library function name external when first used, if nec. */
|
||||
if (! SYMBOL_REF_USED (fun))
|
||||
if (!output_bytecode)
|
||||
{
|
||||
SYMBOL_REF_USED (fun) = 1;
|
||||
ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
|
||||
/* Declare library function name external when first used, if nec. */
|
||||
if (! SYMBOL_REF_USED (fun))
|
||||
{
|
||||
SYMBOL_REF_USED (fun) = 1;
|
||||
ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1166,7 +1354,10 @@ void
|
||||
assemble_label (name)
|
||||
char *name;
|
||||
{
|
||||
ASM_OUTPUT_LABEL (asm_out_file, name);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABEL (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABEL (asm_out_file, name);
|
||||
}
|
||||
|
||||
/* Output to FILE a reference to the assembler name of a C-level name NAME.
|
||||
@ -1181,9 +1372,19 @@ assemble_name (file, name)
|
||||
char *name;
|
||||
{
|
||||
if (name[0] == '*')
|
||||
fputs (&name[1], file);
|
||||
{
|
||||
if (output_bytecode)
|
||||
bc_emit_labelref (name);
|
||||
else
|
||||
fputs (&name[1], file);
|
||||
}
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (file, name);
|
||||
{
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (file, name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate SIZE bytes writable static space with a gensym name
|
||||
@ -1214,12 +1415,21 @@ assemble_static_space (size)
|
||||
strlen (name) + 2);
|
||||
strcpy (namestring, name);
|
||||
|
||||
x = gen_rtx (SYMBOL_REF, Pmode, namestring);
|
||||
if (output_bytecode)
|
||||
x = bc_gen_rtx (namestring, 0, (struct bc_label *) 0);
|
||||
else
|
||||
x = gen_rtx (SYMBOL_REF, Pmode, namestring);
|
||||
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
else
|
||||
{
|
||||
#ifdef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
|
||||
ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, BIGGEST_ALIGNMENT);
|
||||
#else
|
||||
ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
|
||||
#endif
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -1234,6 +1444,10 @@ assemble_trampoline_template ()
|
||||
char *name;
|
||||
int align;
|
||||
|
||||
/* Shouldn't get here */
|
||||
if (output_bytecode)
|
||||
abort ();
|
||||
|
||||
/* By default, put trampoline templates in read-only data section. */
|
||||
|
||||
#ifdef TRAMPOLINE_SECTION
|
||||
@ -1683,9 +1897,13 @@ decode_addr_const (exp, value)
|
||||
break;
|
||||
|
||||
case LABEL_DECL:
|
||||
x = gen_rtx (MEM, FUNCTION_MODE,
|
||||
gen_rtx (LABEL_REF, VOIDmode,
|
||||
label_rtx (TREE_OPERAND (exp, 0))));
|
||||
if (output_bytecode)
|
||||
/* FIXME: this may not be correct, check it */
|
||||
x = bc_gen_rtx (TREE_STRING_POINTER (target), 0, (struct bc_label *) 0);
|
||||
else
|
||||
x = gen_rtx (MEM, FUNCTION_MODE,
|
||||
gen_rtx (LABEL_REF, VOIDmode,
|
||||
label_rtx (TREE_OPERAND (exp, 0))));
|
||||
break;
|
||||
|
||||
case REAL_CST:
|
||||
@ -1699,9 +1917,12 @@ decode_addr_const (exp, value)
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (GET_CODE (x) != MEM)
|
||||
abort ();
|
||||
x = XEXP (x, 0);
|
||||
if (!output_bytecode)
|
||||
{
|
||||
if (GET_CODE (x) != MEM)
|
||||
abort ();
|
||||
x = XEXP (x, 0);
|
||||
}
|
||||
|
||||
value->base = x;
|
||||
value->offset = offset;
|
||||
@ -2171,47 +2392,57 @@ output_constant_def (exp)
|
||||
to see if any of them describes EXP. If yes, the descriptor records
|
||||
the label number already assigned. */
|
||||
|
||||
hash = const_hash (exp) % MAX_HASH_TABLE;
|
||||
|
||||
for (desc = const_hash_table[hash]; desc; desc = desc->next)
|
||||
if (compare_constant (exp, desc))
|
||||
{
|
||||
found = desc->label;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
if (!output_bytecode)
|
||||
{
|
||||
/* No constant equal to EXP is known to have been output.
|
||||
Make a constant descriptor to enter EXP in the hash table.
|
||||
Assign the label number and record it in the descriptor for
|
||||
future calls to this function to find. */
|
||||
|
||||
/* Create a string containing the label name, in LABEL. */
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
|
||||
|
||||
desc = record_constant (exp);
|
||||
desc->next = const_hash_table[hash];
|
||||
desc->label
|
||||
= (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
|
||||
const_hash_table[hash] = desc;
|
||||
hash = const_hash (exp) % MAX_HASH_TABLE;
|
||||
|
||||
for (desc = const_hash_table[hash]; desc; desc = desc->next)
|
||||
if (compare_constant (exp, desc))
|
||||
{
|
||||
found = desc->label;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
/* No constant equal to EXP is known to have been output.
|
||||
Make a constant descriptor to enter EXP in the hash table.
|
||||
Assign the label number and record it in the descriptor for
|
||||
future calls to this function to find. */
|
||||
|
||||
/* Create a string containing the label name, in LABEL. */
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
|
||||
|
||||
desc = record_constant (exp);
|
||||
desc->next = const_hash_table[hash];
|
||||
desc->label
|
||||
= (char *) obstack_copy0 (&permanent_obstack, label, strlen (label));
|
||||
const_hash_table[hash] = desc;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a string containing the label name, in LABEL. */
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We have a symbol name; construct the SYMBOL_REF and the MEM. */
|
||||
|
||||
push_obstacks_nochange ();
|
||||
if (TREE_PERMANENT (exp))
|
||||
end_temporary_allocation ();
|
||||
|
||||
def = gen_rtx (SYMBOL_REF, Pmode, desc->label);
|
||||
|
||||
TREE_CST_RTL (exp)
|
||||
= gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
|
||||
RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
|
||||
if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
|
||||
MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
|
||||
|
||||
if (!output_bytecode)
|
||||
{
|
||||
def = gen_rtx (SYMBOL_REF, Pmode, desc->label);
|
||||
|
||||
TREE_CST_RTL (exp)
|
||||
= gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
|
||||
RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
|
||||
if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
|
||||
MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
|
||||
}
|
||||
pop_obstacks ();
|
||||
|
||||
/* Optionally set flags or add text to the name to record information
|
||||
@ -2283,7 +2514,12 @@ output_constant_def_contents (exp, reloc, labelno)
|
||||
#endif
|
||||
|
||||
if (align > BITS_PER_UNIT)
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
{
|
||||
if (!output_bytecode)
|
||||
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
else
|
||||
BC_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
|
||||
}
|
||||
|
||||
/* Output the label itself. */
|
||||
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", labelno);
|
||||
@ -2891,6 +3127,22 @@ output_addressed_constants (exp)
|
||||
}
|
||||
return reloc;
|
||||
}
|
||||
|
||||
|
||||
/* Output assembler for byte constant */
|
||||
void
|
||||
output_byte_asm (byte)
|
||||
int byte;
|
||||
{
|
||||
if (output_bytecode)
|
||||
bc_emit_const ((char *) &byte, sizeof (char));
|
||||
#ifdef ASM_OUTPUT_BYTE
|
||||
else
|
||||
{
|
||||
ASM_OUTPUT_BYTE (asm_out_file, byte);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Output assembler code for constant EXP to FILE, with no label.
|
||||
This includes the pseudo-op such as ".int" or ".byte", and a newline.
|
||||
@ -2925,7 +3177,10 @@ output_constant (exp, size)
|
||||
This means to fill the space with zeros. */
|
||||
if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
|
||||
{
|
||||
assemble_zeros (size);
|
||||
if (output_bytecode)
|
||||
bc_emit_const_skip (size);
|
||||
else
|
||||
assemble_zeros (size);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3005,6 +3260,101 @@ output_constant (exp, size)
|
||||
if (size > 0)
|
||||
assemble_zeros (size);
|
||||
}
|
||||
|
||||
|
||||
/* Bytecode specific code to output assembler for integer. */
|
||||
void
|
||||
bc_assemble_integer (exp, size)
|
||||
tree exp;
|
||||
int size;
|
||||
{
|
||||
tree const_part;
|
||||
tree addr_part;
|
||||
tree tmp;
|
||||
|
||||
/* FIXME: is this fold() business going to be as good as the
|
||||
expand_expr() using EXPAND_SUM above in the RTL case? I
|
||||
hate RMS.
|
||||
FIXME: Copied as is from BC-GCC1; may need work. Don't hate. -bson */
|
||||
|
||||
exp = fold (exp);
|
||||
|
||||
while (TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR)
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
if (TREE_CODE (exp) == INTEGER_CST)
|
||||
{
|
||||
const_part = exp;
|
||||
addr_part = 0;
|
||||
}
|
||||
else if (TREE_CODE (exp) == PLUS_EXPR)
|
||||
{
|
||||
const_part = TREE_OPERAND (exp, 0);
|
||||
while (TREE_CODE (const_part) == NOP_EXPR
|
||||
|| TREE_CODE (const_part) == CONVERT_EXPR)
|
||||
const_part = TREE_OPERAND (const_part, 0);
|
||||
addr_part = TREE_OPERAND (exp, 1);
|
||||
while (TREE_CODE (addr_part) == NOP_EXPR
|
||||
|| TREE_CODE (addr_part) == CONVERT_EXPR)
|
||||
addr_part = TREE_OPERAND (addr_part, 0);
|
||||
if (TREE_CODE (const_part) != INTEGER_CST)
|
||||
tmp = const_part, const_part = addr_part, addr_part = tmp;
|
||||
if (TREE_CODE (const_part) != INTEGER_CST
|
||||
|| TREE_CODE (addr_part) != ADDR_EXPR)
|
||||
abort (); /* FIXME: we really haven't considered
|
||||
all the possible cases here. */
|
||||
}
|
||||
else if (TREE_CODE (exp) == ADDR_EXPR)
|
||||
{
|
||||
const_part = integer_zero_node;
|
||||
addr_part = exp;
|
||||
}
|
||||
else
|
||||
abort (); /* FIXME: ditto previous. */
|
||||
|
||||
if (addr_part == 0)
|
||||
{
|
||||
if (size == 1)
|
||||
{
|
||||
char c = TREE_INT_CST_LOW (const_part);
|
||||
bc_emit (&c, 1);
|
||||
size -= 1;
|
||||
}
|
||||
else if (size == 2)
|
||||
{
|
||||
short s = TREE_INT_CST_LOW (const_part);
|
||||
bc_emit ((char *) &s, 2);
|
||||
size -= 2;
|
||||
}
|
||||
else if (size == 4)
|
||||
{
|
||||
int i = TREE_INT_CST_LOW (const_part);
|
||||
bc_emit ((char *) &i, 4);
|
||||
size -= 4;
|
||||
}
|
||||
else if (size == 8)
|
||||
{
|
||||
#if WORDS_BIG_ENDIAN
|
||||
int i = TREE_INT_CST_HIGH (const_part);
|
||||
bc_emit ((char *) &i, 4);
|
||||
i = TREE_INT_CST_LOW (const_part);
|
||||
bc_emit ((char *) &i, 4);
|
||||
#else
|
||||
int i = TREE_INT_CST_LOW (const_part);
|
||||
bc_emit ((char *) &i, 4);
|
||||
i = TREE_INT_CST_HIGH (const_part);
|
||||
bc_emit ((char *) &i, 4);
|
||||
#endif
|
||||
size -= 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (size == 4
|
||||
&& TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
|
||||
bc_emit_labelref (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0)),
|
||||
TREE_INT_CST_LOW (const_part));
|
||||
else
|
||||
abort (); /* FIXME: there may be more cases. */
|
||||
}
|
||||
|
||||
/* Subroutine of output_constant, used for CONSTRUCTORs
|
||||
(aggregate constants).
|
||||
@ -3083,7 +3433,10 @@ output_constructor (exp, size)
|
||||
if each element has the proper size. */
|
||||
if ((field != 0 || index != 0) && bitpos != total_bytes)
|
||||
{
|
||||
assemble_zeros (bitpos - total_bytes);
|
||||
if (!output_bytecode)
|
||||
assemble_zeros (bitpos - total_bytes);
|
||||
else
|
||||
bc_emit_const_skip (bitpos - total_bytes);
|
||||
total_bytes = bitpos;
|
||||
}
|
||||
|
||||
@ -3254,3 +3607,42 @@ output_constructor (exp, size)
|
||||
if (total_bytes < size)
|
||||
assemble_zeros (size - total_bytes);
|
||||
}
|
||||
|
||||
|
||||
/* Output asm to handle ``#pragma weak'' */
|
||||
void
|
||||
handle_pragma_weak (what, asm_out_file, name, value)
|
||||
enum pragma_state what;
|
||||
FILE *asm_out_file;
|
||||
char *name, *value;
|
||||
{
|
||||
if (what == ps_name || what == ps_value)
|
||||
{
|
||||
fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
|
||||
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
|
||||
fputc ('\n', asm_out_file);
|
||||
if (what == ps_value)
|
||||
{
|
||||
fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (asm_out_file, name);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, name);
|
||||
|
||||
fputc (',', asm_out_file);
|
||||
if (output_bytecode)
|
||||
BC_OUTPUT_LABELREF (asm_out_file, value);
|
||||
else
|
||||
ASM_OUTPUT_LABELREF (asm_out_file, value);
|
||||
|
||||
fputc ('\n', asm_out_file);
|
||||
}
|
||||
}
|
||||
else if (! (what == ps_done || what == ps_start))
|
||||
warning ("malformed `#pragma weak'");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user