lm32.h revision 1.1.1.2
1/* Definitions of target machine for GNU compiler, Lattice Mico32 architecture.
2   Contributed by Jon Beniston <jon@beniston.com>
3
4   Copyright (C) 2009-2013 Free Software Foundation, Inc.
5
6   This file is part of GCC.
7
8   GCC is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published
10   by the Free Software Foundation; either version 3, or (at your
11   option) any later version.
12
13   GCC is distributed in the hope that it will be useful, but WITHOUT
14   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16   License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with GCC; see the file COPYING3.  If not see
20   <http://www.gnu.org/licenses/>.  */
21
22/*-------------------------------*/
23/* Run-time Target Specification */
24/*-------------------------------*/
25
26/* Target CPU builtins.  */
27#define TARGET_CPU_CPP_BUILTINS()                       \
28  do                                                    \
29    {                                                   \
30      builtin_define ("__lm32__");                      \
31      builtin_assert ("cpu=lm32");                      \
32      builtin_assert ("machine=lm32");                  \
33      if (TARGET_MULTIPLY_ENABLED)                      \
34        builtin_define ("__multiply_enabled__");        \
35      if (TARGET_DIVIDE_ENABLED)                        \
36        builtin_define ("__divide_enabled__");          \
37      if (TARGET_BARREL_SHIFT_ENABLED)                  \
38        builtin_define ("__barrel_shift_enabled__");    \
39      if (TARGET_SIGN_EXTEND_ENABLED)                   \
40        builtin_define ("__sign_extend_enabled__");     \
41      if (TARGET_USER_ENABLED)                          \
42        builtin_define ("__user_enabled__");            \
43    }                                                   \
44  while (0)
45
46#undef  ASM_SPEC
47#define ASM_SPEC "\
48%{mmultiply-enabled} \
49%{mdivide-enabled} \
50%{mbarrel-shift-enabled} \
51%{msign-extend-enabled} \
52%{muser-enabled} \
53"
54
55/* Let link script define all link options.
56   Default to using simulator link script.  */
57
58#undef  STARTFILE_SPEC
59#define STARTFILE_SPEC ""
60#undef  ENDFILE_SPEC
61#define ENDFILE_SPEC ""
62#undef  LIB_SPEC
63#define LIB_SPEC "%{!T*:-T sim.ld}"
64
65#undef  CC1_SPEC
66#define CC1_SPEC "%{G*}"
67
68/*---------------------------------*/
69/* Target machine storage layout.  */
70/*---------------------------------*/
71
72#define BITS_BIG_ENDIAN 0
73#define BYTES_BIG_ENDIAN 1
74#define WORDS_BIG_ENDIAN 1
75
76#define BITS_PER_UNIT 8
77#define BITS_PER_WORD 32
78#define UNITS_PER_WORD 4
79
80#define POINTER_SIZE 32
81
82#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)               \
83do {                                                    \
84  if (GET_MODE_CLASS (MODE) == MODE_INT                 \
85      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)         \
86    (MODE) = word_mode;                                 \
87} while (0)
88
89#define PARM_BOUNDARY 32
90
91#define STACK_BOUNDARY 32
92
93#define BIGGEST_ALIGNMENT 64
94
95#define FUNCTION_BOUNDARY  32
96
97#define EMPTY_FIELD_BOUNDARY 32
98
99#define STRICT_ALIGNMENT 1
100
101#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT
102
103/* Make strings word-aligned so strcpy from constants will be faster.  */
104#define CONSTANT_ALIGNMENT(EXP, ALIGN)  \
105  (TREE_CODE (EXP) == STRING_CST	\
106   && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
107
108/* Make arrays and structures word-aligned to allow faster copying etc.  */
109#define DATA_ALIGNMENT(TYPE, ALIGN)					\
110  ((((ALIGN) < BITS_PER_WORD)						\
111    && (TREE_CODE (TYPE) == ARRAY_TYPE					\
112	|| TREE_CODE (TYPE) == UNION_TYPE				\
113	|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
114
115/* We need this for the same reason as DATA_ALIGNMENT, namely to cause
116   character arrays to be word-aligned so that `strcpy' calls that copy
117   constants to character arrays can be done inline, and 'strcmp' can be
118   optimised to use word loads.  */
119#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
120  DATA_ALIGNMENT (TYPE, ALIGN)
121
122/*----------------------------------------*/
123/* Layout of source language data types.  */
124/*----------------------------------------*/
125
126#define INT_TYPE_SIZE		    32
127#define SHORT_TYPE_SIZE		    16
128#define LONG_TYPE_SIZE		    32
129#define LONG_LONG_TYPE_SIZE	    64
130
131#define FLOAT_TYPE_SIZE		    32
132#define DOUBLE_TYPE_SIZE	    64
133#define LONG_DOUBLE_TYPE_SIZE       64
134
135#define DEFAULT_SIGNED_CHAR         0
136
137#define SIZE_TYPE "unsigned int"
138
139#define PTRDIFF_TYPE "int"
140
141/*---------------------------*/
142/* Standard register usage.  */
143/*---------------------------*/
144
145#define FIRST_PSEUDO_REGISTER  32
146
147#define RV_REGNUM   1
148#define GP_REGNUM   26
149#define FP_REGNUM   27
150#define SP_REGNUM   28
151#define RA_REGNUM   29
152
153#define G_REG_P(X)      ((X)<32)
154
155#define FIXED_REGISTERS   \
156{ 1, 0, 0, 0, 0, 0, 0, 0, \
157  0, 0, 0, 0, 0, 0, 0, 0, \
158  0, 0, 0, 0, 0, 0, 0, 0, \
159  0, 0, 1, 0, 1, 0, 1, 1}
160
161#define CALL_USED_REGISTERS \
162{ 1, 1, 1, 1, 1, 1, 1, 1,   \
163  1, 1, 1, 0, 0, 0, 0, 0,   \
164  0, 0, 0, 0, 0, 0, 0, 0,   \
165  0, 0, 1, 0, 1, 0, 1, 1}
166
167#define HARD_REGNO_NREGS(REGNO, MODE)                                   \
168    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
169
170#define HARD_REGNO_MODE_OK(REGNO, MODE) G_REG_P(REGNO)
171
172#define MODES_TIEABLE_P(MODE1, MODE2)           \
173(      GET_MODE_CLASS (MODE1) == MODE_INT		\
174    && GET_MODE_CLASS (MODE2) == MODE_INT		\
175    && GET_MODE_SIZE (MODE1) <= UNITS_PER_WORD	\
176    && GET_MODE_SIZE (MODE2) <= UNITS_PER_WORD)
177
178#define AVOID_CCMODE_COPIES
179
180/*----------------------------------*/
181/* Register classes and constants.  */
182/*----------------------------------*/
183
184enum reg_class
185{
186  NO_REGS,
187  GENERAL_REGS,
188  ALL_REGS,
189  LIM_REG_CLASSES
190};
191
192#define N_REG_CLASSES (int) LIM_REG_CLASSES
193
194#define REG_CLASS_NAMES { "NO_REGS", "GENERAL_REGS", "ALL_REGS" }
195
196#define REG_CLASS_CONTENTS      \
197{ {0x00000000},                 \
198  {0xffffffff},                 \
199  {0xffffffff}                  \
200}
201
202#define REGNO_REG_CLASS(REGNO) \
203    (G_REG_P(REGNO) ? GENERAL_REGS : NO_REGS)
204
205#define INDEX_REG_CLASS NO_REGS
206
207#define BASE_REG_CLASS GENERAL_REGS
208
209#define REGNO_OK_FOR_BASE_P(REGNO) \
210    (G_REG_P (REGNO) || G_REG_P ((unsigned) reg_renumber[REGNO]))
211
212#define REGNO_OK_FOR_INDEX_P(REGNO) 0
213
214/*----------------------------------------*/
215/* Stack Layout and Calling Conventions.  */
216/*----------------------------------------*/
217
218#define STACK_GROWS_DOWNWARD 1
219
220#define FRAME_GROWS_DOWNWARD 1
221
222#define STACK_POINTER_OFFSET (UNITS_PER_WORD)
223
224#define STARTING_FRAME_OFFSET (UNITS_PER_WORD)
225
226#define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
227
228#define STACK_POINTER_REGNUM SP_REGNUM
229
230#define FRAME_POINTER_REGNUM FP_REGNUM
231
232#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
233
234#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (SImode, RA_REGNUM)
235
236#define RETURN_ADDR_RTX(count, frame)                                   \
237  lm32_return_addr_rtx (count, frame)
238
239/* FIXME - This is not yet supported.  */
240#define STATIC_CHAIN_REGNUM 9
241
242#define ELIMINABLE_REGS \
243{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },                        \
244 { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },                          \
245}
246
247#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
248  (OFFSET) = lm32_compute_initial_elimination_offset (FROM, TO)
249
250/*-----------------------------*/
251/* Function argument passing.  */
252/*-----------------------------*/
253
254#define ACCUMULATE_OUTGOING_ARGS 1
255
256/*--------------------------------*/
257/* Passing Arguments in Registers */
258/*--------------------------------*/
259
260/* The first argument register.  */
261#define LM32_FIRST_ARG_REG 1
262
263/* The number of (integer) argument register available.  */
264#define LM32_NUM_ARG_REGS 8
265
266#define CUMULATIVE_ARGS int
267
268#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED_ARGS)  \
269  (CUM) = 0
270
271#define FUNCTION_ARG_REGNO_P(r)                                         \
272  (((r) >= LM32_FIRST_ARG_REG) && ((r) <= LM32_NUM_ARG_REGS))
273
274/*--------------------*/
275/* Function results.  */
276/*--------------------*/
277
278#define FUNCTION_VALUE(VALTYPE, FUNC)                                   \
279   gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE)                              \
280                 && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)           \
281	            ? word_mode                                         \
282	            : TYPE_MODE (VALTYPE),				\
283	            RV_REGNUM)
284
285#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RV_REGNUM)
286
287#define FUNCTION_VALUE_REGNO_P(N) ((N) == RV_REGNUM)
288
289#define RETURN_IN_MEMORY(TYPE) lm32_return_in_memory (TYPE)
290
291#define DEFAULT_PCC_STRUCT_RETURN 0
292
293/* Convert from bytes to ints.  */
294#define LM32_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
295
296/* The number of (integer) registers required to hold a quantity of
297   type MODE.  */
298#define LM32_NUM_REGS(MODE) LM32_NUM_INTS (GET_MODE_SIZE (MODE))
299
300/* The number of (integer) registers required to hold a quantity of
301   TYPE MODE.  */
302#define LM32_NUM_REGS2(MODE, TYPE)                       \
303  LM32_NUM_INTS ((MODE) == BLKmode ?                     \
304  int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE))
305
306#define STRUCT_VALUE 0
307
308/*---------------------------*/
309/* Function entry and exit.  */
310/*---------------------------*/
311
312/*-------------*/
313/* Profiling.  */
314/*-------------*/
315
316#define FUNCTION_PROFILER(FILE, LABELNO)
317
318/*---------------*/
319/* Trampolines.  */
320/*---------------*/
321
322#define TRAMPOLINE_SIZE		0
323
324/*---------------------*/
325/*  Addressing Modes.  */
326/*---------------------*/
327
328#define CONSTANT_ADDRESS_P(X)						\
329  ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
330    || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH		\
331    || (GET_CODE (X) == CONST)))
332
333#define MAX_REGS_PER_ADDRESS 1
334
335#define STRICT_REG_OK_FOR_BASE_P(X)                                     \
336  (REGNO_OK_FOR_BASE_P (REGNO (X)))
337#define NONSTRICT_REG_OK_FOR_BASE_P(X)                                  \
338  (G_REG_P (REGNO (X)) || !HARD_REGISTER_NUM_P (REGNO (X)))
339
340#ifdef REG_OK_STRICT
341#define REG_OK_FOR_BASE_P(X) STRICT_REG_OK_FOR_BASE_P(X)
342#else
343#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P(X)
344#endif
345
346/*-------------------------*/
347/* Condition Code Status.  */
348/*-------------------------*/
349
350#define REVERSIBLE_CC_MODE(MODE) 1
351
352/*---------*/
353/* Costs.  */
354/*---------*/
355
356#define SLOW_BYTE_ACCESS 1
357
358#define NO_FUNCTION_CSE
359
360#define BRANCH_COST(speed_p, predictable_p) 4
361
362#define MOVE_RATIO(speed) (speed ? 24 : 3)
363
364/*------------*/
365/* Sections.  */
366/*------------*/
367
368#define TEXT_SECTION_ASM_OP             "\t.section\t.text"
369#define DATA_SECTION_ASM_OP             "\t.section\t.data"
370#define SDATA_SECTION_ASM_OP            "\t.section\t.sdata,\"aw\""
371#define BSS_SECTION_ASM_OP              "\t.section\t.bss"
372#define SBSS_SECTION_ASM_OP             "\t.section\t.sbss,\"aw\""
373
374/*-------*/
375/* PIC.  */
376/*-------*/
377
378#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? GP_REGNUM : INVALID_REGNUM)
379
380#define JUMP_TABLES_IN_TEXT_SECTION (flag_pic)
381
382#define LEGITIMATE_PIC_OPERAND_P(X)                                    \
383	(!(nonpic_symbol_mentioned_p (X)))
384
385/*-------------*/
386/* Assembler.  */
387/*-------------*/
388
389#define ASM_COMMENT_START "#"
390
391#define ASM_APP_ON "#APP\n"
392
393#define ASM_APP_OFF "#NO_APP\n"
394
395#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)				\
396 do {									\
397	fputc ( '\t', FILE);						\
398	assemble_name (FILE, LABEL1);					\
399	fputs ( " = ", FILE);						\
400	assemble_name (FILE, LABEL2);					\
401	fputc ( '\n', FILE);						\
402 } while (0)
403
404/* Override default implementation in elfos.h to support -G.  */
405#undef  ASM_OUTPUT_ALIGNED_LOCAL
406#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)		\
407do {									\
408  if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
409    switch_to_section (sbss_section);					\
410  else									\
411    switch_to_section (bss_section);					\
412  ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
413  if (!flag_inhibit_size_directive)					\
414    ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
415  ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
416  ASM_OUTPUT_LABEL(FILE, NAME);						\
417  ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);				\
418} while (0)
419
420/* Override default implementation in elfos.h to support -G.  */
421#undef  ASM_OUTPUT_ALIGNED_COMMON
422#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)		\
423do 									\
424{									\
425  if ((SIZE) <= (unsigned HOST_WIDE_INT) g_switch_value)		\
426    {									\
427      switch_to_section (sbss_section);					\
428      (*targetm.asm_out.globalize_label) (FILE, NAME);			\
429      ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");			\
430      if (!flag_inhibit_size_directive)					\
431	ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, SIZE);			\
432      ASM_OUTPUT_ALIGN ((FILE), exact_log2((ALIGN) / BITS_PER_UNIT));	\
433      ASM_OUTPUT_LABEL(FILE, NAME);					\
434      ASM_OUTPUT_SKIP((FILE), (SIZE) ? (SIZE) : 1);			\
435    }									\
436  else									\
437    {									\
438      switch_to_section (bss_section);					\
439      fprintf ((FILE), "%s", COMMON_ASM_OP);				\
440      assemble_name ((FILE), (NAME));					\
441      fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",          \
442               (SIZE), (ALIGN) / BITS_PER_UNIT);	                \
443    }									\
444}									\
445while (0)
446
447#define ASM_OUTPUT_LABEL(FILE, NAME) \
448  do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0)
449
450#define ASM_OUTPUT_LABELREF(FILE,NAME)	\
451  do {					\
452    const char *xname = (NAME);		\
453    if (xname[0] == '@')		\
454      xname += 1;			\
455    if (xname[0] == '*')		\
456      xname += 1;			\
457    fputs (xname, FILE);		\
458  } while (0)
459
460#define ASM_OUTPUT_SYMBOL_REF(STREAM, SYMBOL)				\
461  do {									\
462    assemble_name (STREAM, XSTR (SYMBOL, 0));				\
463  } while (0)
464
465#define GLOBAL_ASM_OP "\t.global\t"
466
467#define REGISTER_NAMES                                          \
468{                                                               \
469 "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",	        \
470 "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",        \
471 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",        \
472 "r24", "r25",  "gp",  "fp",  "sp",  "ra",  "ea",  "ba"}
473
474#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
475  (((CHAR) == '&') || ((CHAR) == '@') || ((CHAR) == '*'))
476
477#define PRINT_OPERAND(FILE, X, CODE)                            \
478  lm32_print_operand (FILE, X, CODE)
479
480#define PRINT_OPERAND_ADDRESS(FILE, ADDR)                       \
481  lm32_print_operand_address (FILE, ADDR)
482
483#ifndef LOCAL_LABEL_PREFIX
484#define LOCAL_LABEL_PREFIX	"."
485#endif
486
487#define ASM_OUTPUT_ALIGN(FILE,LOG)                              \
488  do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", (1 << (LOG))); } while (0)
489
490#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)                    \
491do {                                                            \
492  char label[64];                                               \
493  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);              \
494  fprintf (FILE, "\n\t.word\t");                                \
495  assemble_name (FILE, label);                                  \
496  fprintf (FILE, "\n");                                         \
497} while (0)
498
499#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)        \
500do {                                                            \
501  char label[64];                                               \
502  fprintf (FILE, "\t.word\t(");                                 \
503  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);		\
504  assemble_name (FILE, label);                                  \
505  fprintf (FILE, "-");                                          \
506  ASM_GENERATE_INTERNAL_LABEL (label, "L", REL);                \
507  assemble_name (FILE, label);                                  \
508  fprintf (FILE, ")\n");                                        \
509} while (0)
510
511/*-------------*/
512/* Debugging.  */
513/*-------------*/
514
515#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
516
517#define DEFAULT_GDB_EXTENSIONS 1
518
519/*--------*/
520/* Misc.  */
521/*--------*/
522
523#define CASE_VECTOR_MODE Pmode
524
525#define WORD_REGISTER_OPERATIONS
526
527#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
528
529#define SHORT_IMMEDIATES_SIGN_EXTEND
530
531#define MOVE_MAX        UNITS_PER_WORD
532#define MAX_MOVE_MAX    4
533
534#define SHIFT_COUNT_TRUNCATED 1
535
536#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
537
538#define Pmode SImode
539
540#define FUNCTION_MODE SImode
541
542#ifndef NO_IMPLICIT_EXTERN_C
543#define NO_IMPLICIT_EXTERN_C
544#endif
545
546#define STORE_FLAG_VALUE 1
547