config.gcc: Add lm32 elf and uclinux targets.

gcc/
2009-11-11  Jon Beniston <jon@beniston.com>

        * config.gcc: Add lm32 elf and uclinux targets.
        * config/lm32: New directory.
        * config/lm32/lm32.c: New file.
        * config/lm32/lm32.h: New file.
        * config/lm32/lm32.md: New file.
        * config/lm32/lm32.opt: New file.
        * config/lm32/lm32-protos.h: New file.
        * config/lm32/constraints.md: New file.
        * config/lm32/predicates.md: New file.
        * config/lm32/sfp-machine.h: New file.
        * config/lm32/t-fprules-softfp: New file.
        * config/lm32/uclinux-elf.h: New file.
        * doc/invoke.texi: Document lm32 options. 
        * doc/contrib.texi: Document lm32 porter.
        * doc/install.texi: Document lm32 targets.

gcc/testsuite/
2009-11-11  Jon Beniston <jon@beniston.com>

        * lib/target-supports.exp (check_profiling_available): lm32 target 
          doesn't support profiling.
        * gcc.dg/20020312-2.c: Add lm32 support.
        * g++.dg/other/packed1.C: Expect to fail on lm32.        
        * g++.old-deja/g++.jason/thunk3.C: Likewise.                 

libgcc/
2009-11-11  Jon Beniston <jon@beniston.com>

        * config.host: Add lm32 targets.
        * config/lm32: New directory.
        * config/lm32/libgcc_lm32.h: New file.
        * config/lm32/_mulsi3.c: New file.
        * config/lm32/_udivmodsi4.c: New file.
        * config/lm32/_divsi3.c: New file.
        * config/lm32/_modsi3.c: New file.
        * config/lm32/_udivsi3.c: New file.
        * config/lm32/_umodsi3.c: New file.
        * config/lm32/_lshrsi3.S: New file.
        * config/lm32/_ashrsi3.S: New file.
        * config/lm32/_ashlsi3.S: New file.
        * config/lm32/crti.S: New file.
        * config/lm32/crtn.S: New file.
        * config/lm32/t-lm32: New file.
        * config/lm32/t-elf: New file.
        * config/lm32/t-uclinux: New file.

From-SVN: r154096
This commit is contained in:
Jon Beniston 2009-11-11 16:43:06 +00:00 committed by Jon Beniston
parent 05d3aa37b3
commit aa4945c138
37 changed files with 4125 additions and 4 deletions

View File

@ -1,3 +1,22 @@
gcc/
2009-11-11 Jon Beniston <jon@beniston.com>
* config.gcc: Add lm32 elf and uclinux targets.
* config/lm32: New directory.
* config/lm32/lm32.c: New file.
* config/lm32/lm32.h: New file.
* config/lm32/lm32.md: New file.
* config/lm32/lm32.opt: New file.
* config/lm32/lm32-protos.h: New file.
* config/lm32/constraints.md: New file.
* config/lm32/predicates.md: New file.
* config/lm32/sfp-machine.h: New file.
* config/lm32/t-fprules-softfp: New file.
* config/lm32/uclinux-elf.h: New file.
* doc/invoke.texi: Document lm32 options.
* doc/contrib.texi: Document lm32 porter.
* doc/install.texi: Document lm32 targets.
2009-11-11 Martin Jambor <mjambor@suse.cz>
PR lto/41932

View File

@ -1469,6 +1469,14 @@ iq2000*-*-elf*)
out_file=iq2000/iq2000.c
md_file=iq2000/iq2000.md
;;
lm32-*-elf*)
tm_file="dbxelf.h elfos.h ${tm_file}"
tmake_file="${tmake_file} lm32/t-fprules-softfp soft-fp/t-softfp"
;;
lm32-*-uclinux*)
tm_file="dbxelf.h elfos.h ${tm_file} linux.h lm32/uclinux-elf.h"
tmake_file="${tmake_file} lm32/t-fprules-softfp soft-fp/t-softfp"
;;
m32r-*-elf*)
tm_file="dbxelf.h elfos.h svr4.h newlib-stdint.h ${tm_file}"
extra_parts="crtinit.o crtfini.o"

View File

@ -0,0 +1,57 @@
;; Constraint definitions for Lattice Mico32 architecture.
;; Contributed by Jon Beniston <jon@beniston.com>
;;
;; Copyright (C) 2009 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_constraint "J"
"The value 0."
(and (match_code "const_int")
(match_test "ival == 0")))
(define_constraint "K"
"A signed 16-bit immediate in the range -32768 to 32767."
(and (match_code "const_int")
(match_test "IN_RANGE (ival, -32768, 32767)")))
(define_constraint "L"
"An unsigned 16-bit immediate in the range 0 to 65535."
(and (match_code "const_int")
(match_test "IN_RANGE (ival, 0, 65535)")))
(define_constraint "M"
"The value 1."
(and (match_code "const_int")
(match_test "ival == 1")))
(define_constraint "U"
"A shifted signed 16-bit constant appropriate for orhi."
(and (match_code "const_int")
(match_test "(ival & 0xffff) == 0
&& (ival >> 31 == -1 || ival >> 31 == 0)")))
(define_constraint "S"
"A symbol in the small data section."
(match_operand 0 "no_pic_small_symbol"))
(define_constraint "Y"
"A high part of a symbol."
(and (match_code "high")
(ior (ior (match_code "symbol_ref" "0")
(match_code "label_ref" "0"))
(match_code "const" "0"))))

View File

@ -0,0 +1,42 @@
/* Prototypes of target machine functions, Lattice Mico32 architecture.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
extern int lm32_return_in_memory (tree type);
extern void lm32_declare_object (FILE *stream, char *name, char *init_string,
char *final_string, int size);
extern void lm32_expand_prologue (void);
extern void lm32_expand_epilogue (void);
extern void lm32_print_operand (FILE *file, rtx op, int letter);
extern void lm32_print_operand_address (FILE *file, rtx addr);
extern rtx lm32_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
tree type, int named);
extern void lm32_override_options (void);
extern HOST_WIDE_INT lm32_compute_initial_elimination_offset (int from,
int to);
extern int lm32_can_use_return (void);
extern rtx lm32_return_addr_rtx (int count, rtx frame);
extern int lm32_expand_block_move (rtx *);
extern int nonpic_symbol_mentioned_p (rtx);
extern rtx lm32_legitimize_pic_address (rtx, enum machine_mode, rtx);
extern void lm32_expand_scc (rtx operands[]);
extern void lm32_expand_conditional_branch (rtx operands[]);
extern bool lm32_move_ok (enum machine_mode, rtx operands[2]);
extern bool lm32_legitimate_constant_p (rtx);

1216
gcc/config/lm32/lm32.c Normal file

File diff suppressed because it is too large Load Diff

581
gcc/config/lm32/lm32.h Normal file
View File

@ -0,0 +1,581 @@
/* Definitions of target machine for GNU compiler, Lattice Mico32 architecture.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/*-------------------------------*/
/* Run-time Target Specification */
/*-------------------------------*/
/* Print subsidiary information on the compiler version in use. */
#ifndef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (LatticeMico32)")
#endif
/* Target CPU builtins. */
#define TARGET_CPU_CPP_BUILTINS() \
do \
{ \
builtin_define ("__lm32__"); \
builtin_assert ("cpu=lm32"); \
builtin_assert ("machine=lm32"); \
if (TARGET_MULTIPLY_ENABLED) \
builtin_define ("__multiply_enabled__"); \
if (TARGET_DIVIDE_ENABLED) \
builtin_define ("__divide_enabled__"); \
if (TARGET_BARREL_SHIFT_ENABLED) \
builtin_define ("__barrel_shift_enabled__"); \
if (TARGET_SIGN_EXTEND_ENABLED) \
builtin_define ("__sign_extend_enabled__"); \
if (TARGET_USER_ENABLED) \
builtin_define ("__user_enabled__"); \
} \
while (0)
#undef ASM_SPEC
#define ASM_SPEC "\
%{mmultiply-enabled} \
%{mdivide-enabled} \
%{mbarrel-shift-enabled} \
%{msign-extend-enabled} \
%{muser-extend-enabled} \
%{v} \
"
/* Let link script define all link options.
Default to using simulator link script. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC ""
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
#undef LIB_SPEC
#define LIB_SPEC "%{!T*:-T sim.ld}"
#define OVERRIDE_OPTIONS lm32_override_options()
extern int target_flags;
/* Add -G xx support. */
#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
/*---------------------------------*/
/* Target machine storage layout. */
/*---------------------------------*/
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 1
#define WORDS_BIG_ENDIAN 1
#define LIBGCC2_WORDS_BIG_ENDIAN 1
#define BITS_PER_UNIT 8
#define BITS_PER_WORD 32
#define UNITS_PER_WORD 4
#define POINTER_SIZE 32
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
do { \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
(MODE) = word_mode; \
} while (0)
#define PARM_BOUNDARY 32
#define STACK_BOUNDARY 32
#define BIGGEST_ALIGNMENT 64
#define FUNCTION_BOUNDARY 32
#define EMPTY_FIELD_BOUNDARY 32
#define STRICT_ALIGNMENT 1
#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
/* Make strings word-aligned so strcpy from constants will be faster. */
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
(TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* Make arrays and structures word-aligned to allow faster copying etc. */
#define DATA_ALIGNMENT(TYPE, ALIGN) \
((((ALIGN) < BITS_PER_WORD) \
&& (TREE_CODE (TYPE) == ARRAY_TYPE \
|| TREE_CODE (TYPE) == UNION_TYPE \
|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
/* We need this for the same reason as DATA_ALIGNMENT, namely to cause
character arrays to be word-aligned so that `strcpy' calls that copy
constants to character arrays can be done inline, and 'strcmp' can be
optimised to use word loads. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
DATA_ALIGNMENT (TYPE, ALIGN)
/*----------------------------------------*/
/* Layout of source language data types. */
/*----------------------------------------*/
#define INT_TYPE_SIZE 32
#define SHORT_TYPE_SIZE 16
#define LONG_TYPE_SIZE 32
#define LONG_LONG_TYPE_SIZE 64
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
#define LONG_DOUBLE_TYPE_SIZE 64
#define DEFAULT_SIGNED_CHAR 0
#define SIZE_TYPE "unsigned int"
#define PTRDIFF_TYPE "int"
/*---------------------------*/
/* Standard register usage. */
/*---------------------------*/
#define FIRST_PSEUDO_REGISTER 32
#define RV_REGNUM 1
#define GP_REGNUM 26
#define FP_REGNUM 27
#define SP_REGNUM 28
#define RA_REGNUM 29
#define G_REG_P(X) ((X)<32)
#define FIXED_REGISTERS \
{ 1, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1, 0, 1, 0, 1, 1}
#define CALL_USED_REGISTERS \
{ 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1, 0, 1, 0, 1, 1}
#define HARD_REGNO_NREGS(REGNO, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define HARD_REGNO_MODE_OK(REGNO, MODE) G_REG_P(REGNO)
#define MODES_TIEABLE_P(MODE1, MODE2) \
( GET_MODE_CLASS (MODE1) == MODE_INT \
&& GET_MODE_CLASS (MODE2) == MODE_INT \
&& GET_MODE_SIZE (MODE1) <= UNITS_PER_WORD \
&& GET_MODE_SIZE (MODE2) <= UNITS_PER_WORD)
#define AVOID_CCMODE_COPIES
/*----------------------------------*/
/* Register classes and constants. */
/*----------------------------------*/
enum reg_class
{
NO_REGS,
GENERAL_REGS,
ALL_REGS,
LIM_REG_CLASSES
};
#define N_REG_CLASSES (int) LIM_REG_CLASSES
#define REG_CLASS_NAMES { "NO_REGS", "GENERAL_REGS", "ALL_REGS" }
#define REG_CLASS_CONTENTS \
{ {0x00000000}, \
{0xffffffff}, \
{0xffffffff} \
}
#define REGNO_REG_CLASS(REGNO) \
(G_REG_P(REGNO) ? GENERAL_REGS : NO_REGS)
#define CLASS_MAX_NREGS(CLASS, MODE) \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define INDEX_REG_CLASS NO_REGS
#define BASE_REG_CLASS GENERAL_REGS
#define REGNO_OK_FOR_BASE_P(REGNO) \
(G_REG_P (REGNO) || G_REG_P ((unsigned) reg_renumber[REGNO]))
#define REGNO_OK_FOR_INDEX_P(REGNO) 0
#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
/*----------------------------------------*/
/* Stack Layout and Calling Conventions. */
/*----------------------------------------*/
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
#define STACK_POINTER_OFFSET (UNITS_PER_WORD)
#define STARTING_FRAME_OFFSET (UNITS_PER_WORD)
#define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
#define STACK_POINTER_REGNUM SP_REGNUM
#define FRAME_POINTER_REGNUM FP_REGNUM
#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
#define RETURN_ADDR_RTX(count, frame) \
lm32_return_addr_rtx (count, frame)
/* FIXME - This is not yet supported. */
#define STATIC_CHAIN_REGNUM 9
#define ELIMINABLE_REGS \
{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
}
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
(OFFSET) = lm32_compute_initial_elimination_offset (FROM, TO)
/*-----------------------------*/
/* Function argument passing. */
/*-----------------------------*/
#define ACCUMULATE_OUTGOING_ARGS 1
#define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
/*--------------------------------*/
/* Passing Arguments in Registers */
/*--------------------------------*/
/* The first argument register. */
#define LM32_FIRST_ARG_REG 1
/* The number of (integer) argument register available. */
#define LM32_NUM_ARG_REGS 8
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
lm32_function_arg ((CUM), (MODE), (TYPE), (NAMED))
#define CUMULATIVE_ARGS int
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED_ARGS) \
(CUM) = 0
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
(CUM) += LM32_NUM_REGS2 (MODE, TYPE)
#define FUNCTION_ARG_REGNO_P(r) \
(((r) >= LM32_FIRST_ARG_REG) && ((r) <= LM32_NUM_ARG_REGS))
/*--------------------*/
/* Function results. */
/*--------------------*/
#define FUNCTION_VALUE(VALTYPE, FUNC) \
gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
&& TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
? word_mode \
: TYPE_MODE (VALTYPE), \
RV_REGNUM)
#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RV_REGNUM)
#define FUNCTION_VALUE_REGNO_P(N) ((N) == RV_REGNUM)
#define RETURN_IN_MEMORY(TYPE) lm32_return_in_memory (TYPE)
#define DEFAULT_PCC_STRUCT_RETURN 0
/* Convert from bytes to ints. */
#define LM32_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* The number of (integer) registers required to hold a quantity of
type MODE. */
#define LM32_NUM_REGS(MODE) LM32_NUM_INTS (GET_MODE_SIZE (MODE))
/* The number of (integer) registers required to hold a quantity of
TYPE MODE. */
#define LM32_NUM_REGS2(MODE, TYPE) \
LM32_NUM_INTS ((MODE) == BLKmode ? \
int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
#define STRUCT_VALUE 0
/*---------------------------*/
/* Function entry and exit. */
/*---------------------------*/
/*-------------*/
/* Profiling. */
/*-------------*/
#define FUNCTION_PROFILER(FILE, LABELNO)
/*---------------*/
/* Trampolines. */
/*---------------*/
#define TRAMPOLINE_SIZE 0
/*---------------------*/
/* Addressing Modes. */
/*---------------------*/
#define CONSTANT_ADDRESS_P(X) \
((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST)))
#define MAX_REGS_PER_ADDRESS 1
#define STRICT_REG_OK_FOR_BASE_P(X) \
(REGNO_OK_FOR_BASE_P (REGNO (X)))
#define NONSTRICT_REG_OK_FOR_BASE_P(X) \
(G_REG_P (REGNO (X)) || !HARD_REGISTER_NUM_P (REGNO (X)))
#ifdef REG_OK_STRICT
#define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P(X)
#else
#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P(X)
#endif
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
if (GET_CODE (ADDR) == PLUS) goto LABEL; \
#define LEGITIMATE_CONSTANT_P(X) lm32_legitimate_constant_p
/*-------------------------*/
/* Condition Code Status. */
/*-------------------------*/
#define REVERSIBLE_CC_MODE(MODE) 1
/*---------*/
/* Costs. */
/*---------*/
#define SLOW_BYTE_ACCESS 1
#define NO_FUNCTION_CSE
#define BRANCH_COST(speed_p, predictable_p) 4
#define MOVE_RATIO(speed) (speed ? 24 : 3)
/*------------*/
/* Sections. */
/*------------*/
#define TEXT_SECTION_ASM_OP "\t.section\t.text"
#define DATA_SECTION_ASM_OP "\t.section\t.data"
#define SDATA_SECTION_ASM_OP "\t.section\t.sdata,\"aw\""
#define BSS_SECTION_ASM_OP "\t.section\t.bss"
#define SBSS_SECTION_ASM_OP "\t.section\t.sbss,\"aw\""
/*-------*/
/* PIC. */
/*-------*/
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? GP_REGNUM : INVALID_REGNUM)
#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
#define LEGITIMATE_PIC_OPERAND_P(X) \
(!(nonpic_symbol_mentioned_p (X)))
/*-------------*/
/* Assembler. */
/*-------------*/
#define ASM_COMMENT_START "#"
#define ASM_APP_ON "#APP\n"
#define ASM_APP_OFF "#NO_APP\n"
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
do { \
fputc ( '\t', FILE); \
assemble_name (FILE, LABEL1); \
fputs ( " = ", FILE); \
assemble_name (FILE, LABEL2); \
fputc ( '\n', FILE); \
} while (0)
/* Override default implementation in elfos.h to support -G. */
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
if ((SIZE) <= g_switch_value) \
switch_to_section (sbss_section); \
else \
switch_to_section (bss_section); \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
if (!flag_inhibit_size_directive) \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
} while (0)
/* Override default implementation in elfos.h to support -G. */
#undef ASM_OUTPUT_ALIGNED_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
do \
{ \
if ((SIZE) <= g_switch_value) \
{ \
switch_to_section (sbss_section); \
(*targetm.asm_out.globalize_label) (FILE, NAME); \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
if (!flag_inhibit_size_directive) \
ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE); \
ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL(FILE, NAME); \
ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1); \
} \
else \
{ \
switch_to_section (bss_section); \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
(SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
} \
while (0)
#define ASM_OUTPUT_LABEL(FILE, NAME) \
do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
do { \
const char *xname = (NAME); \
if (xname[0] == '@') \
xname += 1; \
if (xname[0] == '*') \
xname += 1; \
fputs (xname, FILE); \
} while (0)
#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL) \
do { \
assemble_name (STREAM, XSTR (SYMBOL, 0)); \
} while (0)
#define GLOBAL_ASM_OP "\t.global\t"
#define REGISTER_NAMES \
{ \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
"r24", "r25", "gp", "fp", "sp", "ra", "ea", "ba"}
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
(((CHAR) == '&') || ((CHAR) == '@') || ((CHAR) == '*'))
#define PRINT_OPERAND(FILE, X, CODE) \
lm32_print_operand (FILE, X, CODE)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
lm32_print_operand_address (FILE, ADDR)
#ifndef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
#endif
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", (1 << (LOG))); } while (0)
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do { \
char label[64]; \
ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
fprintf (FILE, "\n\t.word\t"); \
assemble_name (FILE, label); \
fprintf (FILE, "\n"); \
} while (0)
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
do { \
char label[64]; \
fprintf (FILE, "\t.word\t("); \
ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
assemble_name (FILE, label); \
fprintf (FILE, "-"); \
ASM_GENERATE_INTERNAL_LABEL (label, "L", REL); \
assemble_name (FILE, label); \
fprintf (FILE, ")\n"); \
} while (0)
/*-------------*/
/* Debugging. */
/*-------------*/
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
#define CAN_DEBUG_WITHOUT_FP
#define DEFAULT_GDB_EXTENSIONS 1
/*--------*/
/* Misc. */
/*--------*/
#define CASE_VECTOR_MODE Pmode
#define WORD_REGISTER_OPERATIONS
#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
#define SHORT_IMMEDIATES_SIGN_EXTEND
#define MOVE_MAX UNITS_PER_WORD
#define MAX_MOVE_MAX 4
#define SHIFT_COUNT_TRUNCATED 1
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
#define Pmode SImode
#define FUNCTION_MODE SImode
#ifndef NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C
#endif
#define STORE_FLAG_VALUE 1

996
gcc/config/lm32/lm32.md Normal file
View File

@ -0,0 +1,996 @@
;; Machine description of the Lattice Mico32 architecture for GNU C compiler.
;; Contributed by Jon Beniston <jon@beniston.com>
;; Copyright (C) 2009 Free Software Foundation, Inc.
;; This file is part of GCC.
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; Include predicate and constraint definitions
(include "predicates.md")
(include "constraints.md")
;; Register numbers
(define_constants
[(RA_REGNUM 29) ; return address register.
]
)
;; LM32 specific volatile operations
(define_constants
[(UNSPECV_BLOCKAGE 1)] ; prevent scheduling across pro/epilog boundaries
)
;; LM32 specific operations
(define_constants
[(UNSPEC_GOT 2)
(UNSPEC_GOTOFF_HI16 3)
(UNSPEC_GOTOFF_LO16 4)]
)
;; ---------------------------------
;; instruction types
;; ---------------------------------
(define_attr "type"
"unknown,load,store,arith,compare,shift,multiply,divide,call,icall,ubranch,uibranch,cbranch"
(const_string "unknown"))
;; ---------------------------------
;; instruction lengths
;; ---------------------------------
; All instructions are 4 bytes
; Except for branches that are out of range, and have to be implemented
; as two instructions
(define_attr "length" ""
(cond [
(eq_attr "type" "cbranch")
(if_then_else
(lt (abs (minus (match_dup 2) (pc)))
(const_int 32768)
)
(const_int 4)
(const_int 8)
)
]
(const_int 4))
)
;; ---------------------------------
;; scheduling
;; ---------------------------------
(define_automaton "lm32")
(define_cpu_unit "x" "lm32")
(define_cpu_unit "m" "lm32")
(define_cpu_unit "w" "lm32")
(define_insn_reservation "singlecycle" 1
(eq_attr "type" "store,arith,call,icall,ubranch,uibranch,cbranch")
"x")
(define_insn_reservation "twocycle" 2
(eq_attr "type" "compare,shift,divide")
"x,m")
(define_insn_reservation "threecycle" 3
(eq_attr "type" "load,multiply")
"x,m,w")
;; ---------------------------------
;; mov
;; ---------------------------------
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
(match_operand:QI 1 "general_operand" ""))]
""
"
{
if (can_create_pseudo_p ())
{
if (GET_CODE (operand0) == MEM)
{
/* Source operand for store must be in a register. */
operands[1] = force_reg (QImode, operands[1]);
}
}
}")
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
""
"
{
if (can_create_pseudo_p ())
{
if (GET_CODE (operands[0]) == MEM)
{
/* Source operand for store must be in a register. */
operands[1] = force_reg (HImode, operands[1]);
}
}
}")
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"
{
if (can_create_pseudo_p ())
{
if (GET_CODE (operands[0]) == MEM
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == MEM))
{
/* Source operand for store must be in a register. */
operands[1] = force_reg (SImode, operands[1]);
}
}
if (flag_pic && symbolic_operand (operands[1], SImode))
{
if (GET_CODE (operands[1]) == LABEL_REF
|| (GET_CODE (operands[1]) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (operands[1])
&& !SYMBOL_REF_WEAK (operands[1])))
{
emit_insn (gen_movsi_gotoff_hi16 (operands[0], operands[1]));
emit_insn (gen_addsi3 (operands[0],
operands[0],
pic_offset_table_rtx));
emit_insn (gen_movsi_gotoff_lo16 (operands[0],
operands[0],
operands[1]));
}
else
emit_insn (gen_movsi_got (operands[0], operands[1]));
crtl->uses_pic_offset_table = 1;
DONE;
}
else if (flag_pic && GET_CODE (operands[1]) == CONST)
{
rtx op = XEXP (operands[1], 0);
if (GET_CODE (op) == PLUS)
{
rtx arg0 = XEXP (op, 0);
rtx arg1 = XEXP (op, 1);
if (GET_CODE (arg0) == LABEL_REF
|| (GET_CODE (arg0) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (arg0)
&& !SYMBOL_REF_WEAK (arg0)))
{
emit_insn (gen_movsi_gotoff_hi16 (operands[0], arg0));
emit_insn (gen_addsi3 (operands[0],
operands[0],
pic_offset_table_rtx));
emit_insn (gen_movsi_gotoff_lo16 (operands[0],
operands[0],
arg0));
}
else
emit_insn (gen_movsi_got (operands[0], arg0));
emit_insn (gen_addsi3 (operands[0], operands[0], arg1));
crtl->uses_pic_offset_table = 1;
DONE;
}
}
else if (!flag_pic && reloc_operand (operands[1], GET_MODE (operands[1])))
{
emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_HIGH (SImode, operands[1])));
emit_insn (gen_rtx_SET (SImode, operands[0], gen_rtx_LO_SUM (SImode, operands[0], operands[1])));
DONE;
}
else if (GET_CODE (operands[1]) == CONST_INT)
{
if (!(satisfies_constraint_K (operands[1])
|| satisfies_constraint_L (operands[1])
|| satisfies_constraint_U (operands[1])))
{
emit_insn (gen_movsi_insn (operands[0],
GEN_INT (INTVAL (operands[1]) & ~0xffff)));
emit_insn (gen_iorsi3 (operands[0],
operands[0],
GEN_INT (INTVAL (operands[1]) & 0xffff)));
DONE;
}
}
}")
(define_expand "movmemsi"
[(parallel [(set (match_operand:BLK 0 "general_operand" "")
(match_operand:BLK 1 "general_operand" ""))
(use (match_operand:SI 2 "" ""))
(use (match_operand:SI 3 "const_int_operand" ""))])]
""
{
if (!lm32_expand_block_move (operands))
FAIL;
DONE;
})
;; ---------------------------------
;; load/stores/moves
;; ---------------------------------
(define_insn "movsi_got"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "" "")] UNSPEC_GOT))]
"flag_pic"
"lw %0, (gp+got(%1))"
[(set_attr "type" "load")]
)
(define_insn "movsi_gotoff_hi16"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand 1 "" "")] UNSPEC_GOTOFF_HI16))]
"flag_pic"
"orhi %0, r0, gotoffhi16(%1)"
[(set_attr "type" "load")]
)
(define_insn "movsi_gotoff_lo16"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand 2 "" ""))] UNSPEC_GOTOFF_LO16))]
"flag_pic"
"addi %0, %1, gotofflo16(%2)"
[(set_attr "type" "arith")]
)
(define_insn "*movsi_lo_sum"
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "reloc_operand" "i")))]
"!flag_pic"
"ori %0, %0, lo(%2)"
[(set_attr "type" "arith")]
)
(define_insn "*movqi_insn"
[(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,m,r")
(match_operand:QI 1 "general_operand" "m,r,r,J,n"))]
"lm32_move_ok (QImode, operands)"
"@
lbu %0, %1
or %0, %1, r0
sb %0, %1
sb %0, r0
addi %0, r0, %1"
[(set_attr "type" "load,arith,store,store,arith")]
)
(define_insn "*movhi_insn"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,m,r,r")
(match_operand:HI 1 "general_operand" "m,r,r,J,K,L"))]
"lm32_move_ok (HImode, operands)"
"@
lhu %0, %1
or %0, %1, r0
sh %0, %1
sh %0, r0
addi %0, r0, %1
ori %0, r0, %1"
[(set_attr "type" "load,arith,store,store,arith,arith")]
)
(define_insn "movsi_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,m,r,r,r,r,r")
(match_operand:SI 1 "movsi_rhs_operand" "m,r,r,J,K,L,U,S,Y"))]
"lm32_move_ok (SImode, operands)"
"@
lw %0, %1
or %0, %1, r0
sw %0, %1
sw %0, r0
addi %0, r0, %1
ori %0, r0, %1
orhi %0, r0, hi(%1)
mva %0, gp(%1)
orhi %0, r0, hi(%1)"
[(set_attr "type" "load,arith,store,store,arith,arith,arith,arith,arith")]
)
;; ---------------------------------
;; sign and zero extension
;; ---------------------------------
(define_insn "*extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
"TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
"@
lb %0, %1
sextb %0, %1"
[(set_attr "type" "load,arith")]
)
(define_insn "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
""
"@
lbu %0, %1
andi %0, %1, 0xff"
[(set_attr "type" "load,arith")]
)
(define_insn "*extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
"TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
"@
lb %0, %1
sextb %0, %1"
[(set_attr "type" "load,arith")]
)
(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "m,r")))]
""
"@
lbu %0, %1
andi %0, %1, 0xff"
[(set_attr "type" "load,arith")]
)
(define_insn "*extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
"TARGET_SIGN_EXTEND_ENABLED || (GET_CODE (operands[1]) != REG)"
"@
lh %0, %1
sexth %0, %1"
[(set_attr "type" "load,arith")]
)
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
""
"@
lhu %0, %1
andi %0, %1, 0xffff"
[(set_attr "type" "load,arith")]
)
;; ---------------------------------
;; compare
;; ---------------------------------
(define_expand "cstoresi4"
[(set (match_operand:SI 0 "register_operand")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:SI 2 "register_operand")
(match_operand:SI 3 "register_or_int_operand")]))]
""
{
lm32_expand_scc (operands);
DONE;
})
(define_insn "*seq"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(eq:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
""
"@
cmpe %0, %z1, %2
cmpei %0, %z1, %2"
[(set_attr "type" "compare")]
)
(define_insn "*sne"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ne:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
""
"@
cmpne %0, %z1, %2
cmpnei %0, %z1, %2"
[(set_attr "type" "compare")]
)
(define_insn "*sgt"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(gt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
""
"@
cmpg %0, %z1, %2
cmpgi %0, %z1, %2"
[(set_attr "type" "compare")]
)
(define_insn "*sge"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ge:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
""
"@
cmpge %0, %z1, %2
cmpgei %0, %z1, %2"
[(set_attr "type" "compare")]
)
(define_insn "*sgtu"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(gtu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
""
"@
cmpgu %0, %z1, %2
cmpgui %0, %z1, %2"
[(set_attr "type" "compare")]
)
(define_insn "*sgeu"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(geu:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
""
"@
cmpgeu %0, %z1, %2
cmpgeui %0, %z1, %2"
[(set_attr "type" "compare")]
)
;; ---------------------------------
;; unconditional branch
;; ---------------------------------
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
"bi %0"
[(set_attr "type" "ubranch")]
)
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))]
""
"b %0"
[(set_attr "type" "uibranch")]
)
;; ---------------------------------
;; conditional branch
;; ---------------------------------
(define_expand "cbranchsi4"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")])
(label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
lm32_expand_conditional_branch (operands);
DONE;
}")
(define_insn "*beq"
[(set (pc)
(if_then_else (eq:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "be %z0,%z1,%2"
: "bne %z0,%z1,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
(define_insn "*bne"
[(set (pc)
(if_then_else (ne:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "bne %z0,%z1,%2"
: "be %z0,%z1,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
(define_insn "*bgt"
[(set (pc)
(if_then_else (gt:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "bg %z0,%z1,%2"
: "bge %z1,%z0,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
(define_insn "*bge"
[(set (pc)
(if_then_else (ge:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "bge %z0,%z1,%2"
: "bg %z1,%z0,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
(define_insn "*bgtu"
[(set (pc)
(if_then_else (gtu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "bgu %z0,%z1,%2"
: "bgeu %z1,%z0,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
(define_insn "*bgeu"
[(set (pc)
(if_then_else (geu:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
(match_operand:SI 1 "register_or_zero_operand" "rJ"))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
return get_attr_length (insn) == 4
? "bgeu %z0,%z1,%2"
: "bgu %z1,%z0,8\n\tbi %2";
}
[(set_attr "type" "cbranch")])
;; ---------------------------------
;; call
;; ---------------------------------
(define_expand "call"
[(parallel [(call (match_operand 0 "" "")
(match_operand 1 "" ""))
(clobber (reg:SI RA_REGNUM))
])]
""
"
{
rtx addr = XEXP (operands[0], 0);
if (!CONSTANT_ADDRESS_P (addr))
XEXP (operands[0], 0) = force_reg (Pmode, addr);
}")
(define_insn "*call"
[(call (mem:SI (match_operand:SI 0 "call_operand" "r,s"))
(match_operand 1 "" ""))
(clobber (reg:SI RA_REGNUM))]
""
"@
call %0
calli %0"
[(set_attr "type" "call,icall")]
)
(define_expand "call_value"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "" "")
(match_operand 2 "" "")))
(clobber (reg:SI RA_REGNUM))
])]
""
"
{
rtx addr = XEXP (operands[1], 0);
if (!CONSTANT_ADDRESS_P (addr))
XEXP (operands[1], 0) = force_reg (Pmode, addr);
}")
(define_insn "*call_value"
[(set (match_operand 0 "register_operand" "=r,r")
(call (mem:SI (match_operand:SI 1 "call_operand" "r,s"))
(match_operand 2 "" "")))
(clobber (reg:SI RA_REGNUM))]
""
"@
call %1
calli %1"
[(set_attr "type" "call,icall")]
)
(define_insn "return_internal"
[(use (match_operand:SI 0 "register_operand" "r"))
(return)]
""
"b %0"
[(set_attr "type" "uibranch")]
)
(define_insn "return"
[(return)]
"lm32_can_use_return ()"
"ret"
[(set_attr "type" "uibranch")]
)
;; ---------------------------------
;; switch/case statements
;; ---------------------------------
(define_expand "tablejump"
[(set (pc) (match_operand 0 "register_operand" ""))
(use (label_ref (match_operand 1 "" "")))]
""
"
{
rtx target = operands[0];
if (flag_pic)
{
/* For PIC, the table entry is relative to the start of the table. */
rtx label = gen_reg_rtx (SImode);
target = gen_reg_rtx (SImode);
emit_move_insn (label, gen_rtx_LABEL_REF (SImode, operands[1]));
emit_insn (gen_addsi3 (target, operands[0], label));
}
emit_jump_insn (gen_tablejumpsi (target, operands[1]));
DONE;
}")
(define_insn "tablejumpsi"
[(set (pc) (match_operand:SI 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))]
""
"b %0"
[(set_attr "type" "ubranch")]
)
;; ---------------------------------
;; arithmetic
;; ---------------------------------
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
""
"@
add %0, %z1, %2
addi %0, %z1, %2"
[(set_attr "type" "arith")]
)
(define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:SI 2 "register_or_zero_operand" "rJ")))]
""
"sub %0, %z1, %z2"
[(set_attr "type" "arith")]
)
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(mult:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_K_operand" "r,K")))]
"TARGET_MULTIPLY_ENABLED"
"@
mul %0, %z1, %2
muli %0, %z1, %2"
[(set_attr "type" "multiply")]
)
(define_insn "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(udiv:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_DIVIDE_ENABLED"
"divu %0, %z1, %2"
[(set_attr "type" "divide")]
)
(define_insn "umodsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(umod:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:SI 2 "register_operand" "r")))]
"TARGET_DIVIDE_ENABLED"
"modu %0, %z1, %2"
[(set_attr "type" "divide")]
)
;; ---------------------------------
;; negation and inversion
;; ---------------------------------
(define_insn "negsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
""
"sub %0, r0, %z1"
[(set_attr "type" "arith")]
)
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")))]
""
"not %0, %z1"
[(set_attr "type" "arith")]
)
;; ---------------------------------
;; logical
;; ---------------------------------
(define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(and:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
""
"@
and %0, %z1, %2
andi %0, %z1, %2"
[(set_attr "type" "arith")]
)
(define_insn "iorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
""
"@
or %0, %z1, %2
ori %0, %z1, %2"
[(set_attr "type" "arith")]
)
(define_insn "xorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
""
"@
xor %0, %z1, %2
xori %0, %z1, %2"
[(set_attr "type" "arith")]
)
(define_insn "*norsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(not:SI (ior:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L"))))]
""
"@
nor %0, %z1, %2
nori %0, %z1, %2"
[(set_attr "type" "arith")]
)
(define_insn "*xnorsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L"))))]
""
"@
xnor %0, %z1, %2
xnori %0, %z1, %2"
[(set_attr "type" "arith")]
)
;; ---------------------------------
;; shifts
;; ---------------------------------
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "register_or_zero_operand" "")
(match_operand:SI 2 "register_or_L_operand" "")))]
""
{
if (!TARGET_BARREL_SHIFT_ENABLED)
{
if (!optimize_size
&& satisfies_constraint_L (operands[2])
&& INTVAL (operands[2]) <= 8)
{
int i;
int shifts = INTVAL (operands[2]);
rtx one = GEN_INT (1);
if (shifts == 0)
emit_move_insn (operands[0], operands[1]);
else
emit_insn (gen_addsi3 (operands[0], operands[1], operands[1]));
for (i = 1; i < shifts; i++)
emit_insn (gen_addsi3 (operands[0], operands[0], operands[0]));
DONE;
}
else
FAIL;
}
})
(define_insn "*ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
"TARGET_BARREL_SHIFT_ENABLED"
"@
sl %0, %z1, %2
sli %0, %z1, %2"
[(set_attr "type" "shift")]
)
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
(match_operand:SI 2 "register_or_L_operand" "")))]
""
{
if (!TARGET_BARREL_SHIFT_ENABLED)
{
if (!optimize_size
&& satisfies_constraint_L (operands[2])
&& INTVAL (operands[2]) <= 8)
{
int i;
int shifts = INTVAL (operands[2]);
rtx one = GEN_INT (1);
if (shifts == 0)
emit_move_insn (operands[0], operands[1]);
else
emit_insn (gen_ashrsi3_1bit (operands[0], operands[1], one));
for (i = 1; i < shifts; i++)
emit_insn (gen_ashrsi3_1bit (operands[0], operands[0], one));
DONE;
}
else
FAIL;
}
})
(define_insn "*ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
"TARGET_BARREL_SHIFT_ENABLED"
"@
sr %0, %z1, %2
sri %0, %z1, %2"
[(set_attr "type" "shift")]
)
(define_insn "ashrsi3_1bit"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:SI 2 "constant_M_operand" "M")))]
"!TARGET_BARREL_SHIFT_ENABLED"
"sri %0, %z1, %2"
[(set_attr "type" "shift")]
)
(define_expand "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "")
(match_operand:SI 2 "register_or_L_operand" "")))]
""
{
if (!TARGET_BARREL_SHIFT_ENABLED)
{
if (!optimize_size
&& satisfies_constraint_L (operands[2])
&& INTVAL (operands[2]) <= 8)
{
int i;
int shifts = INTVAL (operands[2]);
rtx one = GEN_INT (1);
if (shifts == 0)
emit_move_insn (operands[0], operands[1]);
else
emit_insn (gen_lshrsi3_1bit (operands[0], operands[1], one));
for (i = 1; i < shifts; i++)
emit_insn (gen_lshrsi3_1bit (operands[0], operands[0], one));
DONE;
}
else
FAIL;
}
})
(define_insn "*lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ,rJ")
(match_operand:SI 2 "register_or_L_operand" "r,L")))]
"TARGET_BARREL_SHIFT_ENABLED"
"@
sru %0, %z1, %2
srui %0, %z1, %2"
[(set_attr "type" "shift")]
)
(define_insn "lshrsi3_1bit"
[(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
(match_operand:SI 2 "constant_M_operand" "M")))]
"!TARGET_BARREL_SHIFT_ENABLED"
"srui %0, %z1, %2"
[(set_attr "type" "shift")]
)
;; ---------------------------------
;; function entry / exit
;; ---------------------------------
(define_expand "prologue"
[(const_int 1)]
""
"
{
lm32_expand_prologue ();
DONE;
}")
(define_expand "epilogue"
[(return)]
""
"
{
lm32_expand_epilogue ();
DONE;
}")
;; ---------------------------------
;; nop
;; ---------------------------------
(define_insn "nop"
[(const_int 0)]
""
"nop"
[(set_attr "type" "arith")]
)
;; ---------------------------------
;; blockage
;; ---------------------------------
;; used to stop the scheduler from
;; scheduling code across certain boundaries
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
""
""
[(set_attr "length" "0")]
)

40
gcc/config/lm32/lm32.opt Normal file
View File

@ -0,0 +1,40 @@
; Options for the Lattice Mico32 port of the compiler.
; Contributed by Jon Beniston <jon@beniston.com>
;
; Copyright (C) 2009 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License as published
; by the Free Software Foundation; either version 3, or (at your
; option) any later version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
; License for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
mmultiply-enabled
Target Report Mask(MULTIPLY_ENABLED)
Enable multiply instructions
mdivide-enabled
Target Report Mask(DIVIDE_ENABLED)
Enable divide and modulus instructions
mbarrel-shift-enabled
Target Report Mask(BARREL_SHIFT_ENABLED)
Enable barrel shift instructions
msign-extend-enabled
Target Report Mask(SIGN_EXTEND_ENABLED)
Enable sign extend instructions
muser-enabled
Target Report Mask(USER_ENABLED)
Enable user-defined instructions

View File

@ -0,0 +1,77 @@
;; Predicate definitions for Lattice Mico32 architecture.
;; Contributed by Jon Beniston <jon@beniston.com>
;;
;; Copyright (C) 2009 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;;
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_predicate "const0_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
(define_predicate "constant_K_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_K (op)")))
(define_predicate "constant_L_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_L (op)")))
(define_predicate "constant_M_operand"
(and (match_code "const_int")
(match_test "satisfies_constraint_M (op)")))
(define_predicate "register_or_zero_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "const0_operand")))
(define_predicate "register_or_K_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "constant_K_operand")))
(define_predicate "register_or_L_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "constant_L_operand")))
(define_predicate "register_or_int_operand"
(ior (match_operand 0 "register_operand")
(match_code "const_int")))
(define_predicate "reloc_operand"
(ior (ior (match_code "label_ref")
(match_code "symbol_ref"))
(match_code "const")))
(define_predicate "symbolic_operand"
(ior (match_code "label_ref")
(match_code "symbol_ref")))
(define_predicate "no_pic_small_symbol"
(match_code "symbol_ref")
{
return !flag_pic && SYMBOL_REF_SMALL_P (op);
})
(define_predicate "call_operand"
(ior (match_code "symbol_ref")
(match_operand 0 "register_operand")))
(define_predicate "movsi_rhs_operand"
(ior (match_operand 0 "nonimmediate_operand")
(ior (match_code "const_int")
(ior (match_test "satisfies_constraint_S (op)")
(match_test "satisfies_constraint_Y (op)")))))

View File

@ -0,0 +1,51 @@
#define _FP_W_TYPE_SIZE 32
#define _FP_W_TYPE unsigned long
#define _FP_WS_TYPE signed long
#define _FP_I_TYPE long
#define _FP_MUL_MEAT_S(R,X,Y) \
_FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_D(R,X,Y) \
_FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_MUL_MEAT_Q(R,X,Y) \
_FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
#define _FP_NANSIGN_S 0
#define _FP_NANSIGN_D 0
#define _FP_NANSIGN_Q 0
#define _FP_KEEPNANFRACP 1
/* Someone please check this. */
#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
do { \
if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
&& !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
{ \
R##_s = Y##_s; \
_FP_FRAC_COPY_##wc(R,Y); \
} \
else \
{ \
R##_s = X##_s; \
_FP_FRAC_COPY_##wc(R,X); \
} \
R##_c = FP_CLS_NAN; \
} while (0)
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __BIG_ENDIAN
/* Define ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));

View File

@ -0,0 +1,5 @@
softfp_float_modes := sf df
softfp_int_modes := si di
softfp_extensions := sfdf
softfp_truncations := dfsf
softfp_machine_header := lm32/sfp-machine.h

View File

@ -0,0 +1,85 @@
/* Definitions for LM32 running Linux-based GNU systems using ELF
Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
2009 Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* elfos.h should have already been included. Now just override
any conflicting definitions and add any extras. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (LM32 GNU/Linux with ELF)", stderr);
/* Do not assume anything about header files. */
#undef NO_IMPLICIT_EXTERN_C
#define NO_IMPLICIT_EXTERN_C
/* The GNU C++ standard library requires that these macros be defined. */
#undef CPLUSPLUS_CPP_SPEC
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
/* Now we define the strings used to build the spec file. */
#undef LIB_SPEC
#define LIB_SPEC \
"%{pthread:-lpthread} \
%{shared:-lc} \
%{!shared:-lc} "
#define LIBGCC_SPEC "-lgcc"
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
object constructed before entering `main'. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
%{!p:%{profile:gcrt1.o%s} \
%{!profile:crt1.o%s}}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
the GNU/Linux magical crtend.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
object constructed before entering `main', followed by a normal
GNU/Linux "finalizer" file, `crtn.o'. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
#undef LINK_SPEC
#define LINK_SPEC "%{h*} %{version:-v} \
%{b} %{Wl,*:%*} \
%{static:-Bstatic} \
%{shared:-shared} \
%{symbolic:-Bsymbolic} \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}"
#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
#undef CC1_SPEC
#define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"

View File

@ -55,7 +55,7 @@ Scott Bambrough for help porting the Java compiler.
Wolfgang Bangerth for processing tons of bug reports.
@item
Jon Beniston for his Microsoft Windows port of Java.
Jon Beniston for his Microsoft Windows port of Java and port to Lattice Mico32.
@item
Daniel Berlin for better DWARF2 support, faster/better optimizations,

View File

@ -2888,6 +2888,10 @@ information are.
@item
@uref{#iq2000-x-elf,,iq2000-*-elf}
@item
@uref{#lm32-x-elf,,lm32-*-elf}
@item
@uref{#lm32-x-uclinux,,lm32-*-uclinux}
@item
@uref{#m32c-x-elf,,m32c-*-elf}
@item
@uref{#m32r-x-elf,,m32r-*-elf}
@ -3663,6 +3667,20 @@ switch and using the configure option @option{--with-cpu-@var{cpu_type}}.
Vitesse IQ2000 processors. These are used in embedded
applications. There are no standard Unix configurations.
@html
<hr />
@end html
@heading @anchor{lm32-x-elf}lm32-*-elf
Lattice Mico32 processor.
This configuration is intended for embedded systems.
@html
<hr />
@end html
@heading @anchor{lm32-x-uclinux}lm32-*-uclinux
Lattice Mico32 processor.
This configuration is intended for embedded systems running uClinux.
@html
<hr />
@end html

View File

@ -631,6 +631,10 @@ Objective-C and Objective-C++ Dialects}.
@emph{IA-64/VMS Options}
@gccoptlist{-mvms-return-codes -mdebug-main=@var{prefix} -mmalloc64}
@emph{LM32 Options}
@gccoptlist{-mbarrel-shift-enabled -mdivide-enabled -mmultiply-enabled @gol
-msign-extend-enabled -muser-enabled}
@emph{M32R/D Options}
@gccoptlist{-m32r2 -m32rx -m32r @gol
-mdebug @gol
@ -9534,6 +9538,7 @@ platform.
* i386 and x86-64 Windows Options::
* IA-64 Options::
* IA-64/VMS Options::
* LM32 Options::
* M32C Options::
* M32R/D Options::
* M680x0 Options::
@ -12565,6 +12570,35 @@ routine for the debugger.
Default to 64bit memory allocation routines.
@end table
@node LM32 Options
@subsection LM32 Options
@cindex LM32 options
These @option{-m} options are defined for the Lattice Mico32 architecture:
@table @gcctabopt
@item -mbarrel-shift-enabled
@opindex mbarrel-shift-enabled
Enable barrel-shift instructions.
@item -mdivide-enabled
@opindex mdivide-enabled
Enable divide and modulus instructions.
@item -mmultiply-enabled
@opindex multiply-enabled
Enable multiply instructions.
@item -msign-extend-enabled
@opindex msign-extend-enabled
Enable sign extend instructions.
@item -muser-enabled
@opindex muser-enabled
Enable user-defined instructions.
@end table
@node M32C Options
@subsection M32C Options
@cindex M32C options

View File

@ -1,3 +1,12 @@
gcc/testsuite/
2009-11-11 Jon Beniston <jon@beniston.com>
* lib/target-supports.exp (check_profiling_available): lm32 target
doesn't support profiling.
* gcc.dg/20020312-2.c: Add lm32 support.
* g++.dg/other/packed1.C: Expect to fail on lm32.
* g++.old-deja/g++.jason/thunk3.C: Likewise.
2009-11-11 Daniel Jacobowitz <dan@codesourcery.com>
* gcc.target/arm/neon: Regenerate generated tests.

View File

@ -1,4 +1,4 @@
// { dg-do run { xfail arm-*-* sh-*-* } }
// { dg-do run { xfail arm-*-* sh-*-* lm32-*-* } }
// NMS:2003-04-21 this fails on strict aligned architectures again,
// the patch was reverted because it broke something more important.

View File

@ -1,4 +1,4 @@
// { dg-do run { xfail rs6000-*-* powerpc-*-eabi mn10300-*-* v850-*-* sh-*-* sh64-*-* h8*-*-* xtensa*-*-* m32r*-*-* } }
// { dg-do run { xfail rs6000-*-* powerpc-*-eabi mn10300-*-* v850-*-* sh-*-* sh64-*-* h8*-*-* xtensa*-*-* m32r*-*-* lm32-*-* } }
// Test that variadic function calls using thunks work right.
// Note that this will break on any target that uses the generic thunk
// support, because it doesn't support variadic functions.

View File

@ -30,6 +30,8 @@ extern void abort (void);
# define PIC_REG "ebx"
#elif defined(__ia64__)
/* PIC register is r1, but is used even without -fpic. */
#elif defined(__lm32__)
/* No pic register. */
#elif defined(__M32R__)
/* No pic register. */
#elif defined(__m68k__)

View File

@ -496,7 +496,8 @@ proc check_profiling_available { test_what } {
|| [istarget crisv32-*-*]
|| [istarget fido-*-elf]
|| [istarget h8300-*-*]
|| [istarget m32c-*-elf]
|| [istarget lm32-*-*]
|| [istarget m32c-*-elf]
|| [istarget m68k-*-elf]
|| [istarget m68k-*-uclinux*]
|| [istarget mep-*-elf]

View File

@ -1,3 +1,24 @@
libgcc/
2009-11-11 Jon Beniston <jon@beniston.com>
* config.host: Add lm32 targets.
* config/lm32: New directory.
* config/lm32/libgcc_lm32.h: New file.
* config/lm32/_mulsi3.c: New file.
* config/lm32/_udivmodsi4.c: New file.
* config/lm32/_divsi3.c: New file.
* config/lm32/_modsi3.c: New file.
* config/lm32/_udivsi3.c: New file.
* config/lm32/_umodsi3.c: New file.
* config/lm32/_lshrsi3.S: New file.
* config/lm32/_ashrsi3.S: New file.
* config/lm32/_ashlsi3.S: New file.
* config/lm32/crti.S: New file.
* config/lm32/crtn.S: New file.
* config/lm32/t-lm32: New file.
* config/lm32/t-elf: New file.
* config/lm32/t-uclinux: New file.
2009-10-26 Nick Clifton <nickc@redhat.com>
* config.host: Add support for RX target.

View File

@ -97,6 +97,9 @@ ia64-*-*)
hppa*-*-*)
cpu_type=pa
;;
lm32*-*-*)
cpu_type=lm32
;;
m32r*-*-*)
cpu_type=m32r
;;
@ -354,6 +357,14 @@ ia64-hp-*vms*)
;;
iq2000*-*-elf*)
;;
lm32-*-elf*)
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
tmake_file="lm32/t-lm32 lm32/t-elf t-softfp"
;;
lm32-*-uclinux*)
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
tmake_file="lm32/t-lm32 lm32/t-uclinux t-softfp"
;;
m32r-*-elf*|m32r-*-rtems*)
;;
m32rle-*-elf*)

View File

@ -0,0 +1,114 @@
# _ashlsi3.S for Lattice Mico32
# Contributed by Jon Beniston <jon@beniston.com> and Richard Henderson.
#
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License and
# a copy of the GCC Runtime Library Exception along with this program;
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
#
/* Arithmetic left shift. */
.text
.global __ashlsi3
.type __ashlsi3,@function
.align 4
__ashlsi3:
/* Only use 5 LSBs, as that's all the h/w shifter uses. */
andi r2, r2, 0x1f
/* Get address of offset into unrolled shift loop to jump to. */
#ifdef __PIC__
lw r3, (gp+got(__ashlsi3_0))
#else
mvhi r3, hi(__ashlsi3_0)
ori r3, r3, lo(__ashlsi3_0)
#endif
add r2, r2, r2
add r2, r2, r2
sub r3, r3, r2
b r3
__ashlsi3_31:
add r1, r1, r1
__ashlsi3_30:
add r1, r1, r1
__ashlsi3_29:
add r1, r1, r1
__ashlsi3_28:
add r1, r1, r1
__ashlsi3_27:
add r1, r1, r1
__ashlsi3_26:
add r1, r1, r1
__ashlsi3_25:
add r1, r1, r1
__ashlsi3_24:
add r1, r1, r1
__ashlsi3_23:
add r1, r1, r1
__ashlsi3_22:
add r1, r1, r1
__ashlsi3_21:
add r1, r1, r1
__ashlsi3_20:
add r1, r1, r1
__ashlsi3_19:
add r1, r1, r1
__ashlsi3_18:
add r1, r1, r1
__ashlsi3_17:
add r1, r1, r1
__ashlsi3_16:
add r1, r1, r1
__ashlsi3_15:
add r1, r1, r1
__ashlsi3_14:
add r1, r1, r1
__ashlsi3_13:
add r1, r1, r1
__ashlsi3_12:
add r1, r1, r1
__ashlsi3_11:
add r1, r1, r1
__ashlsi3_10:
add r1, r1, r1
__ashlsi3_9:
add r1, r1, r1
__ashlsi3_8:
add r1, r1, r1
__ashlsi3_7:
add r1, r1, r1
__ashlsi3_6:
add r1, r1, r1
__ashlsi3_5:
add r1, r1, r1
__ashlsi3_4:
add r1, r1, r1
__ashlsi3_3:
add r1, r1, r1
__ashlsi3_2:
add r1, r1, r1
__ashlsi3_1:
add r1, r1, r1
__ashlsi3_0:
ret

View File

@ -0,0 +1,110 @@
# _ashrsi3.S for Lattice Mico32
# Contributed by Jon Beniston <jon@beniston.com> and Richard Henderson.
#
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License and
# a copy of the GCC Runtime Library Exception along with this program;
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
#
/* Arithmetic right shift. */
.global __ashrsi3
.type __ashrsi3,@function
__ashrsi3:
/* Only use 5 LSBs, as that's all the h/w shifter uses. */
andi r2, r2, 0x1f
/* Get address of offset into unrolled shift loop to jump to. */
#ifdef __PIC__
lw r3, (gp+got(__ashrsi3_0))
#else
mvhi r3, hi(__ashrsi3_0)
ori r3, r3, lo(__ashrsi3_0)
#endif
add r2, r2, r2
add r2, r2, r2
sub r3, r3, r2
b r3
__ashrsi3_31:
sri r1, r1, 1
__ashrsi3_30:
sri r1, r1, 1
__ashrsi3_29:
sri r1, r1, 1
__ashrsi3_28:
sri r1, r1, 1
__ashrsi3_27:
sri r1, r1, 1
__ashrsi3_26:
sri r1, r1, 1
__ashrsi3_25:
sri r1, r1, 1
__ashrsi3_24:
sri r1, r1, 1
__ashrsi3_23:
sri r1, r1, 1
__ashrsi3_22:
sri r1, r1, 1
__ashrsi3_21:
sri r1, r1, 1
__ashrsi3_20:
sri r1, r1, 1
__ashrsi3_19:
sri r1, r1, 1
__ashrsi3_18:
sri r1, r1, 1
__ashrsi3_17:
sri r1, r1, 1
__ashrsi3_16:
sri r1, r1, 1
__ashrsi3_15:
sri r1, r1, 1
__ashrsi3_14:
sri r1, r1, 1
__ashrsi3_13:
sri r1, r1, 1
__ashrsi3_12:
sri r1, r1, 1
__ashrsi3_11:
sri r1, r1, 1
__ashrsi3_10:
sri r1, r1, 1
__ashrsi3_9:
sri r1, r1, 1
__ashrsi3_8:
sri r1, r1, 1
__ashrsi3_7:
sri r1, r1, 1
__ashrsi3_6:
sri r1, r1, 1
__ashrsi3_5:
sri r1, r1, 1
__ashrsi3_4:
sri r1, r1, 1
__ashrsi3_3:
sri r1, r1, 1
__ashrsi3_2:
sri r1, r1, 1
__ashrsi3_1:
sri r1, r1, 1
__ashrsi3_0:
ret

View File

@ -0,0 +1,99 @@
/* _divsi3 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Signed integer division. */
static const UQItype __divsi3_table[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 4, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 5, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 6, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 7, 3, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 8, 4, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 9, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 10, 5, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 11, 5, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 12, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 13, 6, 4, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 14, 7, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0,
0, 15, 7, 5, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
};
SItype
__divsi3 (SItype a, SItype b)
{
int neg = 0;
SItype res;
int cfg;
if (b == 0)
{
/* Raise divide by zero exception. */
int eba, sr;
/* Save interrupt enable. */
__asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
sr = (sr & 1) << 1;
__asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
/* Branch to exception handler. */
__asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
eba += 32 * 5;
__asm__ __volatile__ ("mv ea, ra");
__asm__ __volatile__ ("b %0"::"r" (eba));
__builtin_unreachable ();
}
if (((USItype) (a | b)) < 16)
res = __divsi3_table[(a << 4) + b];
else
{
if (a < 0)
{
a = -a;
neg = !neg;
}
if (b < 0)
{
b = -b;
neg = !neg;
}
__asm__ ("rcsr %0, CFG":"=r" (cfg));
if (cfg & 2)
__asm__ ("divu %0, %1, %2": "=r" (res):"r" (a), "r" (b));
else
res = __udivmodsi4 (a, b, 0);
if (neg)
res = -res;
}
return res;
}

View File

@ -0,0 +1,109 @@
# _lshrsi3.S for Lattice Mico32
# Contributed by Jon Beniston <jon@beniston.com> and Richard Henderson.
#
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License and
# a copy of the GCC Runtime Library Exception along with this program;
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
#
/* Logical right shift. */
.global __lshrsi3
.type __lshrsi3,@function
__lshrsi3:
/* Only use 5 LSBs, as that's all the h/w shifter uses. */
andi r2, r2, 0x1f
/* Get address of offset into unrolled shift loop to jump to. */
#ifdef __PIC__
lw r3, (gp+got(__lshrsi3_0))
#else
mvhi r3, hi(__lshrsi3_0)
ori r3, r3, lo(__lshrsi3_0)
#endif
add r2, r2, r2
add r2, r2, r2
sub r3, r3, r2
b r3
__lshrsi3_31:
srui r1, r1, 1
__lshrsi3_30:
srui r1, r1, 1
__lshrsi3_29:
srui r1, r1, 1
__lshrsi3_28:
srui r1, r1, 1
__lshrsi3_27:
srui r1, r1, 1
__lshrsi3_26:
srui r1, r1, 1
__lshrsi3_25:
srui r1, r1, 1
__lshrsi3_24:
srui r1, r1, 1
__lshrsi3_23:
srui r1, r1, 1
__lshrsi3_22:
srui r1, r1, 1
__lshrsi3_21:
srui r1, r1, 1
__lshrsi3_20:
srui r1, r1, 1
__lshrsi3_19:
srui r1, r1, 1
__lshrsi3_18:
srui r1, r1, 1
__lshrsi3_17:
srui r1, r1, 1
__lshrsi3_16:
srui r1, r1, 1
__lshrsi3_15:
srui r1, r1, 1
__lshrsi3_14:
srui r1, r1, 1
__lshrsi3_13:
srui r1, r1, 1
__lshrsi3_12:
srui r1, r1, 1
__lshrsi3_11:
srui r1, r1, 1
__lshrsi3_10:
srui r1, r1, 1
__lshrsi3_9:
srui r1, r1, 1
__lshrsi3_8:
srui r1, r1, 1
__lshrsi3_7:
srui r1, r1, 1
__lshrsi3_6:
srui r1, r1, 1
__lshrsi3_5:
srui r1, r1, 1
__lshrsi3_4:
srui r1, r1, 1
__lshrsi3_3:
srui r1, r1, 1
__lshrsi3_2:
srui r1, r1, 1
__lshrsi3_1:
srui r1, r1, 1
__lshrsi3_0:
ret

View File

@ -0,0 +1,71 @@
/* _modsi3 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Signed integer modulus. */
SItype
__modsi3 (SItype a, SItype b)
{
int neg = 0;
SItype res;
int cfg;
if (b == 0)
{
/* Raise divide by zero exception. */
int eba, sr;
/* Save interrupt enable. */
__asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
sr = (sr & 1) << 1;
__asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
/* Branch to exception handler. */
__asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
eba += 32 * 5;
__asm__ __volatile__ ("mv ea, ra");
__asm__ __volatile__ ("b %0"::"r" (eba));
__builtin_unreachable ();
}
if (a < 0)
{
a = -a;
neg = 1;
}
if (b < 0)
b = -b;
__asm__ ("rcsr %0, CFG":"=r" (cfg));
if (cfg & 2)
__asm__ ("modu %0, %1, %2": "=r" (res):"r" (a), "r" (b));
else
res = __udivmodsi4 (a, b, 1);
if (neg)
res = -res;
return res;
}

View File

@ -0,0 +1,48 @@
/* _mulsi3 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Integer multiplication. */
USItype
__mulsi3 (USItype a, USItype b)
{
USItype result;
result = 0;
if (a == 0)
return 0;
while (b != 0)
{
if (b & 1)
result += a;
a <<= 1;
b >>= 1;
}
return result;
}

View File

@ -0,0 +1,53 @@
/* _udivmodsi4 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Unsigned integer division/modulus. */
USItype
__udivmodsi4 (USItype num, USItype den, int modwanted)
{
USItype bit = 1;
USItype res = 0;
while (den < num && bit && !(den & (1L << 31)))
{
den <<= 1;
bit <<= 1;
}
while (bit)
{
if (num >= den)
{
num -= den;
res |= bit;
}
bit >>= 1;
den >>= 1;
}
if (modwanted)
return num;
return res;
}

View File

@ -0,0 +1,49 @@
/* _udivsi3 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Unsigned integer division. */
USItype
__udivsi3 (USItype a, USItype b)
{
if (b == 0)
{
/* Raise divide by zero exception. */
int eba, sr;
/* Save interrupt enable. */
__asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
sr = (sr & 1) << 1;
__asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
/* Branch to exception handler. */
__asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
eba += 32 * 5;
__asm__ __volatile__ ("mv ea, ra");
__asm__ __volatile__ ("b %0"::"r" (eba));
__builtin_unreachable ();
}
return __udivmodsi4 (a, b, 0);
}

View File

@ -0,0 +1,49 @@
/* _umodsi3 for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#include "libgcc_lm32.h"
/* Unsigned modulus. */
USItype
__umodsi3 (USItype a, USItype b)
{
if (b == 0)
{
/* Raise divide by zero exception. */
int eba, sr;
/* Save interrupt enable. */
__asm__ __volatile__ ("rcsr %0, IE":"=r" (sr));
sr = (sr & 1) << 1;
__asm__ __volatile__ ("wcsr IE, %0"::"r" (sr));
/* Branch to exception handler. */
__asm__ __volatile__ ("rcsr %0, EBA":"=r" (eba));
eba += 32 * 5;
__asm__ __volatile__ ("mv ea, ra");
__asm__ __volatile__ ("b %0"::"r" (eba));
__builtin_unreachable ();
}
return __udivmodsi4 (a, b, 1);
}

40
libgcc/config/lm32/crti.S Normal file
View File

@ -0,0 +1,40 @@
# crti.S for Lattice Mico32
# Contributed by Jon Beniston <jon@beniston.com>
#
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License and
# a copy of the GCC Runtime Library Exception along with this program;
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
#
.section .init
.global _init
.type _init,@function
.align 4
_init:
addi sp, sp, -4
sw (sp+4), ra
.section .fini
.global _fini
.type _fini,@function
.align 4
_fini:
addi sp, sp, -4
sw (sp+4), ra

37
libgcc/config/lm32/crtn.S Normal file
View File

@ -0,0 +1,37 @@
# crtn.S for Lattice Mico32
# Contributed by Jon Beniston <jon@beniston.com>
#
# Copyright (C) 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# Under Section 7 of GPL version 3, you are granted additional
# permissions described in the GCC Runtime Library Exception, version
# 3.1, as published by the Free Software Foundation.
#
# You should have received a copy of the GNU General Public License and
# a copy of the GCC Runtime Library Exception along with this program;
# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
# <http://www.gnu.org/licenses/>.
#
.section .init
lw ra, (sp+4)
addi sp, sp, 4
ret
.section .fini
lw ra, (sp+4)
addi sp, sp, 4
ret

View File

@ -0,0 +1,43 @@
/* Integer arithmetic support for Lattice Mico32.
Contributed by Jon Beniston <jon@beniston.com>
Copyright (C) 2009 Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef LIBGCC_LM32_H
#define LIBGCC_LM32_H
/* Types. */
typedef unsigned char UQItype __attribute__ ((mode (QI)));
typedef long SItype __attribute__ ((mode (SI)));
typedef unsigned long USItype __attribute__ ((mode (SI)));
/* Prototypes. */
USItype __mulsi3 (USItype a, USItype b);
USItype __udivmodsi4 (USItype num, USItype den, int modwanted);
SItype __divsi3 (SItype a, SItype b);
SItype __modsi3 (SItype a, SItype b);
USItype __udivsi3 (USItype a, USItype b);
USItype __umodsi3 (USItype a, USItype b);
#endif /* LIBGCC_LM32_H */

12
libgcc/config/lm32/t-elf Normal file
View File

@ -0,0 +1,12 @@
# Assemble startup files.
$(T)crti.o: $(srcdir)/config/lm32/crti.S $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/lm32/crti.S
$(T)crtn.o: $(srcdir)/config/lm32/crtn.S $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/lm32/crtn.S
CRTSTUFF_T_CFLAGS = -G 0 -msign-extend-enabled
HOST_LIBGCC2_CFLAGS = -G 0 -msign-extend-enabled

12
libgcc/config/lm32/t-lm32 Normal file
View File

@ -0,0 +1,12 @@
LIB2ADD += \
$(srcdir)/config/lm32/_ashlsi3.S \
$(srcdir)/config/lm32/_ashrsi3.S \
$(srcdir)/config/lm32/_lshrsi3.S \
$(srcdir)/config/lm32/_mulsi3.c \
$(srcdir)/config/lm32/_udivmodsi4.c \
$(srcdir)/config/lm32/_divsi3.c \
$(srcdir)/config/lm32/_modsi3.c \
$(srcdir)/config/lm32/_udivsi3.c \
$(srcdir)/config/lm32/_umodsi3.c
MULTILIB_OPTIONS = mmultiply-enabled mbarrel-shift-enabled

View File

@ -0,0 +1,2 @@
CRTSTUFF_T_CFLAGS = -fPIC -msign-extend-enabled
HOST_LIBGCC2_CFLAGS = -fPIC -msign-extend-enabled