OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [microblaze/] [microblaze.h] - Blame information for rev 709

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
/* Definitions of target machine for GNU compiler for Xilinx MicroBlaze.
2
   Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
3
 
4
   Contributed by Michael Eager <eager@eagercon.com>.
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
/* Standard GCC variables that we reference.  */
23
 
24
/* MicroBlaze external variables defined in microblaze.c.  */
25
 
26
/* Which pipeline to schedule for.  */
27
enum pipeline_type
28
{
29
  MICROBLAZE_PIPE_3 = 0,
30
  MICROBLAZE_PIPE_5 = 1
31
};
32
 
33
#define MICROBLAZE_MASK_NO_UNSAFE_DELAY         0x00000001
34
 
35
/* print_operand punctuation chars */
36
extern char microblaze_print_operand_punct[];
37
 
38
/* # bytes of data/sdata cutoff */
39
extern int microblaze_section_threshold;
40
 
41
/* Map register # to debug register # */
42
extern int microblaze_dbx_regno[];
43
 
44
extern int microblaze_no_unsafe_delay;
45
extern enum pipeline_type microblaze_pipe;
46
 
47
#define OBJECT_FORMAT_ELF
48
 
49
/* Default target_flags if no switches are specified  */
50
#define TARGET_DEFAULT      (MASK_SOFT_MUL | MASK_SOFT_DIV | MASK_SOFT_FLOAT)
51
 
52
/* What is the default setting for -mcpu= . We set it to v4.00.a even though
53
   we are actually ahead. This is safest version that has generate code
54
   compatible for the original ISA */
55
#define MICROBLAZE_DEFAULT_CPU      "v4.00.a"
56
 
57
/* Macros to decide whether certain features are available or not,
58
   depending on the instruction set architecture level.  */
59
 
60
#define DRIVER_SELF_SPECS                               \
61
        "%{mxl-soft-mul:%<mno-xl-soft-mul}",            \
62
        "%{mno-xl-barrel-shift:%<mxl-barrel-shift}",    \
63
        "%{mno-xl-pattern-compare:%<mxl-pattern-compare}", \
64
        "%{mxl-soft-div:%<mno-xl-soft-div}",            \
65
        "%{msoft-float:%<mhard-float}"
66
 
67
/* Tell collect what flags to pass to nm.  */
68
#ifndef NM_FLAGS
69
#define NM_FLAGS "-Bn"
70
#endif
71
 
72
/* Names to predefine in the preprocessor for this target machine.  */
73
#define TARGET_CPU_CPP_BUILTINS() microblaze_cpp_define (pfile)
74
 
75
/* Assembler specs.  */
76
 
77
#define TARGET_ASM_SPEC ""
78
 
79
#define ASM_SPEC "\
80
%(target_asm_spec)"
81
 
82
/* Extra switches sometimes passed to the linker.  */
83
/* -xl-mode-xmdstub translated to -Zxl-mode-xmdstub -- deprecated.  */
84
 
85
#define LINK_SPEC "%{shared:-shared} -N -relax \
86
  %{Zxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \
87
  %{mxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \
88
  %{mxl-gp-opt:%{G*}} %{!mxl-gp-opt: -G 0} \
89
  %{!T*: -dT xilinx.ld%s}"
90
 
91
/* Specs for the compiler proper  */
92
 
93
#ifndef CC1_SPEC
94
#define CC1_SPEC " \
95
%{G*} \
96
%(subtarget_cc1_spec) \
97
%{mxl-multiply-high:-mcpu=v6.00.a} \
98
"
99
#endif
100
 
101
#define EXTRA_SPECS                                                     \
102
  { "target_asm_spec", TARGET_ASM_SPEC },                               \
103
  SUBTARGET_EXTRA_SPECS
104
 
105
/* Local compiler-generated symbols must have a prefix that the assembler
106
   understands.   */
107
 
108
#ifndef LOCAL_LABEL_PREFIX
109
#define LOCAL_LABEL_PREFIX      "$"
110
#endif
111
 
112
/* fixed registers.  */
113
#define MB_ABI_BASE_REGNUM                   0
114
#define MB_ABI_STACK_POINTER_REGNUM          1
115
#define MB_ABI_GPRO_REGNUM                   2
116
#define MB_ABI_GPRW_REGNUM                  13
117
#define MB_ABI_INTR_RETURN_ADDR_REGNUM      14
118
#define MB_ABI_SUB_RETURN_ADDR_REGNUM       15
119
#define MB_ABI_DEBUG_RETURN_ADDR_REGNUM     16
120
#define MB_ABI_EXCEPTION_RETURN_ADDR_REGNUM 17
121
#define MB_ABI_ASM_TEMP_REGNUM              18
122
/* This is our temp register.  */
123
#define MB_ABI_FRAME_POINTER_REGNUM         19
124
#define MB_ABI_PIC_ADDR_REGNUM              20
125
#define MB_ABI_PIC_FUNC_REGNUM              21
126
/* Volatile registers.  */
127
#define MB_ABI_INT_RETURN_VAL_REGNUM         3
128
#define MB_ABI_INT_RETURN_VAL2_REGNUM        4
129
#define MB_ABI_FIRST_ARG_REGNUM              5
130
#define MB_ABI_LAST_ARG_REGNUM              10
131
#define MB_ABI_MAX_ARG_REGS                 (MB_ABI_LAST_ARG_REGNUM     \
132
                                             - MB_ABI_FIRST_ARG_REGNUM + 1)
133
#define MB_ABI_STATIC_CHAIN_REGNUM           3
134
#define MB_ABI_TEMP1_REGNUM                 11
135
#define MB_ABI_TEMP2_REGNUM                 12
136
#define MB_ABI_MSR_SAVE_REG                 11
137
/* Volatile register used to save MSR in interrupt handlers.  */
138
 
139
 
140
/* Debug stuff.  */
141
 
142
/* How to renumber registers for dbx and gdb.  */
143
#define DBX_REGISTER_NUMBER(REGNO) microblaze_dbx_regno[(REGNO)]
144
 
145
/* Generate DWARF exception handling info.  */
146
#define DWARF2_UNWIND_INFO 1
147
 
148
/* Don't generate .loc operations.  */
149
#define DWARF2_ASM_LINE_DEBUG_INFO 0
150
 
151
/* The DWARF 2 CFA column which tracks the return address.  */
152
#define DWARF_FRAME_RETURN_COLUMN \
153
        (GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)
154
 
155
/* Initial state of return address on entry to func = R15.
156
   Actually, the RA is at R15+8, but gcc doesn't know how
157
   to generate this.
158
   NOTE:  GDB has a workaround and expects this incorrect value.
159
   If this is fixed, a corresponding fix to GDB is needed.  */
160
#define INCOMING_RETURN_ADDR_RTX                        \
161
  gen_rtx_REG (VOIDmode, GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM)
162
 
163
/* Use DWARF 2 debugging information by default.  */
164
#define DWARF2_DEBUGGING_INFO
165
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
166
 
167
/* Target machine storage layout */
168
 
169
#define BITS_BIG_ENDIAN 0
170
#define BYTES_BIG_ENDIAN 1
171
#define WORDS_BIG_ENDIAN 1
172
#define BITS_PER_UNIT           8
173
#define BITS_PER_WORD           32
174
#define UNITS_PER_WORD          4
175
#define MIN_UNITS_PER_WORD      4
176
#define INT_TYPE_SIZE           32
177
#define SHORT_TYPE_SIZE         16
178
#define LONG_TYPE_SIZE          32
179
#define LONG_LONG_TYPE_SIZE     64
180
#define FLOAT_TYPE_SIZE         32
181
#define DOUBLE_TYPE_SIZE        64
182
#define LONG_DOUBLE_TYPE_SIZE   64
183
#define POINTER_SIZE            32
184
#define PARM_BOUNDARY           32
185
#define FUNCTION_BOUNDARY       32
186
#define EMPTY_FIELD_BOUNDARY    32
187
#define STRUCTURE_SIZE_BOUNDARY 8
188
#define BIGGEST_ALIGNMENT       32
189
#define STRICT_ALIGNMENT        1
190
#define PCC_BITFIELD_TYPE_MATTERS 1
191
 
192
#define CONSTANT_ALIGNMENT(EXP, ALIGN)                                  \
193
  ((TREE_CODE (EXP) == STRING_CST  || TREE_CODE (EXP) == CONSTRUCTOR)   \
194
   && (ALIGN) < BITS_PER_WORD                                           \
195
        ? BITS_PER_WORD                                                 \
196
        : (ALIGN))
197
 
198
#define DATA_ALIGNMENT(TYPE, ALIGN)                                     \
199
  ((((ALIGN) < BITS_PER_WORD)                                           \
200
    && (TREE_CODE (TYPE) == ARRAY_TYPE                                  \
201
        || TREE_CODE (TYPE) == UNION_TYPE                               \
202
        || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
203
 
204
#define LOCAL_ALIGNMENT(TYPE, ALIGN)                                    \
205
    (((TREE_CODE (TYPE) == ARRAY_TYPE                                   \
206
       && TYPE_MODE (TREE_TYPE (TYPE)) == QImode)                       \
207
     && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))
208
 
209
#define WORD_REGISTER_OPERATIONS
210
 
211
#define LOAD_EXTEND_OP(MODE)  ZERO_EXTEND
212
 
213
#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE)     \
214
  if (GET_MODE_CLASS (MODE) == MODE_INT         \
215
      && GET_MODE_SIZE (MODE) < 4)              \
216
    (MODE) = SImode;
217
 
218
/* Standard register usage.  */
219
 
220
/* On the MicroBlaze, we have 32 integer registers */
221
 
222
#define FIRST_PSEUDO_REGISTER 36
223
 
224
#define FIXED_REGISTERS                                                 \
225
{                                                                       \
226
  1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,                       \
227
  1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                       \
228
  1, 1, 1, 1                                                            \
229
}
230
 
231
#define CALL_USED_REGISTERS                                             \
232
{                                                                       \
233
  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                       \
234
  1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                       \
235
  1, 1, 1, 1                                                            \
236
}
237
 
238
#define GP_REG_FIRST    0
239
#define GP_REG_LAST     31
240
#define GP_REG_NUM      (GP_REG_LAST - GP_REG_FIRST + 1)
241
#define GP_DBX_FIRST    0
242
 
243
#define ST_REG          32
244
#define AP_REG_NUM      33
245
#define RAP_REG_NUM     34
246
#define FRP_REG_NUM     35
247
 
248
#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
249
#define ST_REG_P(REGNO) ((REGNO) == ST_REG)
250
 
251
#define HARD_REGNO_NREGS(REGNO, MODE)                                   \
252
        ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
253
 
254
/* Value is 1 if hard register REGNO can hold a value of machine-mode
255
   MODE.  In 32 bit mode, require that DImode and DFmode be in even
256
   registers.  For DImode, this makes some of the insns easier to
257
   write, since you don't have to worry about a DImode value in
258
   registers 3 & 4, producing a result in 4 & 5.
259
 
260
   To make the code simpler HARD_REGNO_MODE_OK now just references an
261
   array built in override_options.  Because machmodes.h is not yet
262
   included before this file is processed, the MODE bound can't be
263
   expressed here.  */
264
extern char microblaze_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
265
#define HARD_REGNO_MODE_OK(REGNO, MODE)                                 \
266
            microblaze_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO)]
267
 
268
#define MODES_TIEABLE_P(MODE1, MODE2)                                   \
269
  ((GET_MODE_CLASS (MODE1) == MODE_FLOAT ||                             \
270
    GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT)                       \
271
   == (GET_MODE_CLASS (MODE2) == MODE_FLOAT ||                          \
272
       GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
273
 
274
#define STACK_POINTER_REGNUM   (GP_REG_FIRST + MB_ABI_STACK_POINTER_REGNUM)
275
 
276
#define STACK_POINTER_OFFSET   FIRST_PARM_OFFSET(FNDECL)
277
 
278
/* Base register for access to local variables of the function.  We
279
   pretend that the frame pointer is
280
   MB_ABI_INTR_RETURN_ADDR_REGNUM, and then eliminate it
281
   to HARD_FRAME_POINTER_REGNUM.  We can get away with this because
282
   rMB_ABI_INTR_RETUREN_ADDR_REGNUM is a fixed
283
   register(return address for interrupt), and will not be used for
284
   anything else.  */
285
 
286
#define FRAME_POINTER_REGNUM            FRP_REG_NUM
287
#define HARD_FRAME_POINTER_REGNUM       \
288
        (GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM)
289
#define ARG_POINTER_REGNUM              AP_REG_NUM
290
#define RETURN_ADDRESS_POINTER_REGNUM   RAP_REG_NUM
291
#define STATIC_CHAIN_REGNUM             \
292
        (GP_REG_FIRST + MB_ABI_STATIC_CHAIN_REGNUM)
293
 
294
/* registers used in prologue/epilogue code when the stack frame
295
   is larger than 32K bytes.  These registers must come from the
296
   scratch register set, and not used for passing and returning
297
   arguments and any other information used in the calling sequence
298
   (such as pic).  */
299
 
300
#define MICROBLAZE_TEMP1_REGNUM         \
301
        (GP_REG_FIRST + MB_ABI_TEMP1_REGNUM)
302
 
303
#define MICROBLAZE_TEMP2_REGNUM         \
304
        (GP_REG_FIRST + MB_ABI_TEMP2_REGNUM)
305
 
306
#define NO_FUNCTION_CSE                 1
307
 
308
#define PIC_OFFSET_TABLE_REGNUM         \
309
        (flag_pic ? (GP_REG_FIRST + MB_ABI_PIC_ADDR_REGNUM) : \
310
        INVALID_REGNUM)
311
 
312
enum reg_class
313
{
314
  NO_REGS,                      /* no registers in set.  */
315
  GR_REGS,                      /* integer registers.  */
316
  ST_REGS,                      /* status register.  */
317
  ALL_REGS,                     /* all registers.  */
318
  LIM_REG_CLASSES               /* max value + 1.  */
319
};
320
 
321
#define N_REG_CLASSES           (int) LIM_REG_CLASSES
322
 
323
#define GENERAL_REGS            GR_REGS
324
 
325
#define REG_CLASS_NAMES                                                 \
326
{                                                                       \
327
  "NO_REGS",                                                            \
328
  "GR_REGS",                                                            \
329
  "ST_REGS",                                                            \
330
  "ALL_REGS"                                                            \
331
}
332
 
333
#define REG_CLASS_CONTENTS                                              \
334
{                                                                       \
335
  { 0x00000000, 0x00000000 },           /* no registers.  */            \
336
  { 0xffffffff, 0x00000000 },           /* integer registers.  */       \
337
  { 0x00000000, 0x00000001 },           /* status registers.  */        \
338
  { 0xffffffff, 0x0000000f }            /* all registers.  */           \
339
}
340
 
341
extern enum reg_class microblaze_regno_to_class[];
342
 
343
#define REGNO_REG_CLASS(REGNO)          microblaze_regno_to_class[ (REGNO) ]
344
 
345
#define BASE_REG_CLASS                  GR_REGS
346
 
347
#define INDEX_REG_CLASS                 GR_REGS
348
 
349
#define GR_REG_CLASS_P(CLASS)           ((CLASS) == GR_REGS)
350
 
351
/* REGISTER AND CONSTANT CLASSES */
352
 
353
#define SMALL_INT(X) ((unsigned HOST_WIDE_INT) (INTVAL (X) + 0x8000) < 0x10000)
354
#define LARGE_INT(X) \
355
  (INTVAL (X) > 0 && UINTVAL (X) >= 0x80000000 && UINTVAL (X) <= 0xffffffff)
356
#define PLT_ADDR_P(X) (GET_CODE (X) == UNSPEC && XINT (X,1) == UNSPEC_PLT)
357
/* Test for a valid operand for a call instruction.
358
   Don't allow the arg pointer register or virtual regs
359
   since they may change into reg + const, which the patterns
360
   can't handle yet.  */
361
#define CALL_INSN_OP(X) (CONSTANT_ADDRESS_P (X) \
362
                         || (GET_CODE (X) == REG && X != arg_pointer_rtx\
363
                             && ! (REGNO (X) >= FIRST_PSEUDO_REGISTER   \
364
                             && REGNO (X) <= LAST_VIRTUAL_REGISTER)))
365
 
366
/* True if VALUE is a signed 16-bit number.  */
367
#define SMALL_OPERAND(VALUE)                                            \
368
  ((unsigned HOST_WIDE_INT) (VALUE) + 0x8000 < 0x10000)
369
 
370
/* Constant which cannot be loaded in one instruction.  */
371
#define LARGE_OPERAND(VALUE)                                            \
372
  ((((VALUE) & ~0x0000ffff) != 0)                                       \
373
   && (((VALUE) & ~0x0000ffff) != ~0x0000ffff)                          \
374
   && (((VALUE) & 0x0000ffff) != 0                                      \
375
       || (((VALUE) & ~2147483647) != 0                                 \
376
           && ((VALUE) & ~2147483647) != ~2147483647)))
377
 
378
#define PREFERRED_RELOAD_CLASS(X,CLASS)                                 \
379
  ((CLASS) != ALL_REGS                                                  \
380
   ? (CLASS)                                                    \
381
   : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT                      \
382
       || GET_MODE_CLASS (GET_MODE (X)) == MODE_COMPLEX_FLOAT)          \
383
      ? (GR_REGS)                       \
384
      : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_INT                     \
385
          || GET_MODE (X) == VOIDmode)                                  \
386
         ? (GR_REGS) : (CLASS))))
387
 
388
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE)                   \
389
  (GET_MODE_CLASS (MODE) == MODE_INT)
390
 
391
/* Stack layout; function entry, exit and calling.  */
392
 
393
#define STACK_GROWS_DOWNWARD
394
 
395
/* Changed the starting frame offset to including the new link stuff */
396
#define STARTING_FRAME_OFFSET                                           \
397
   (crtl->outgoing_args_size + FIRST_PARM_OFFSET(FNDECL))
398
 
399
/* The return address for the current frame is in r31 if this is a leaf
400
   function.  Otherwise, it is on the stack.  It is at a variable offset
401
   from sp/fp/ap, so we define a fake hard register rap which is a
402
   poiner to the return address on the stack.  This always gets eliminated
403
   during reload to be either the frame pointer or the stack pointer plus
404
   an offset.  */
405
 
406
#define RETURN_ADDR_RTX(count, frame)                   \
407
  microblaze_return_addr(count,frame)
408
 
409
extern struct microblaze_frame_info current_frame_info;
410
 
411
#define ELIMINABLE_REGS                                                 \
412
{{ ARG_POINTER_REGNUM,   STACK_POINTER_REGNUM},                         \
413
 { ARG_POINTER_REGNUM,   GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM},   \
414
 { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},                \
415
 { RETURN_ADDRESS_POINTER_REGNUM,                                       \
416
   GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM},                         \
417
 { RETURN_ADDRESS_POINTER_REGNUM,                                       \
418
   GP_REG_FIRST + MB_ABI_SUB_RETURN_ADDR_REGNUM},                       \
419
 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                         \
420
 { FRAME_POINTER_REGNUM, GP_REG_FIRST + MB_ABI_FRAME_POINTER_REGNUM}}
421
 
422
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                     \
423
        (OFFSET) = microblaze_initial_elimination_offset ((FROM), (TO))
424
 
425
#define ACCUMULATE_OUTGOING_ARGS        1
426
 
427
#define FIRST_PARM_OFFSET(FNDECL)               (UNITS_PER_WORD)
428
 
429
#define ARG_POINTER_CFA_OFFSET(FNDECL)          0
430
 
431
#define REG_PARM_STACK_SPACE(FNDECL)            (MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD)
432
 
433
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE)   1
434
 
435
#define STACK_BOUNDARY                          32
436
 
437
#define NUM_OF_ARGS                             6
438
 
439
#define GP_RETURN                               (GP_REG_FIRST + MB_ABI_INT_RETURN_VAL_REGNUM)
440
 
441
#define GP_ARG_FIRST                            (GP_REG_FIRST + MB_ABI_FIRST_ARG_REGNUM)
442
#define GP_ARG_LAST                             (GP_REG_FIRST + MB_ABI_LAST_ARG_REGNUM)
443
 
444
#define MAX_ARGS_IN_REGISTERS                   MB_ABI_MAX_ARG_REGS
445
 
446
#define LIBCALL_VALUE(MODE)                                             \
447
  gen_rtx_REG (                                                         \
448
           ((GET_MODE_CLASS (MODE) != MODE_INT                          \
449
             || GET_MODE_SIZE (MODE) >= 4)                              \
450
            ? (MODE)                                                    \
451
            : SImode), GP_RETURN)
452
 
453
/* 1 if N is a possible register number for a function value.
454
   On the MicroBlaze, R2 R3 are the only register thus used.
455
   Currently, R2 are only implemented  here (C has no complex type)  */
456
 
457
#define FUNCTION_VALUE_REGNO_P(N)               ((N) == GP_RETURN)
458
 
459
#define FUNCTION_ARG_REGNO_P(N)                 (((N) >= GP_ARG_FIRST && (N) <= GP_ARG_LAST))
460
 
461
typedef struct microblaze_args
462
{
463
  int gp_reg_found;             /* whether a gp register was found yet */
464
  int arg_number;               /* argument number */
465
  int arg_words;                /* # total words the arguments take */
466
  int fp_arg_words;             /* # words for FP args */
467
  int last_arg_fp;              /* nonzero if last arg was FP (EABI only) */
468
  int fp_code;                  /* Mode of FP arguments */
469
  int num_adjusts;              /* number of adjustments made */
470
  /* Adjustments made to args pass in regs.  */
471
  /* ??? The size is doubled to work around a bug in the code that sets the
472
     adjustments in function_arg.  */
473
  rtx adjust[MAX_ARGS_IN_REGISTERS * 2];
474
} CUMULATIVE_ARGS;
475
 
476
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS)    \
477
  init_cumulative_args (&CUM, FNTYPE, LIBNAME)
478
 
479
#define NO_PROFILE_COUNTERS                     1
480
 
481
#define FUNCTION_PROFILER(FILE, LABELNO) { \
482
  {                                        \
483
    fprintf (FILE, "\tbrki\tr16,_mcount\n");           \
484
  }                                                    \
485
 }
486
 
487
#define EXIT_IGNORE_STACK                       1
488
 
489
#define TRAMPOLINE_SIZE                         (32 + 8)
490
 
491
#define TRAMPOLINE_ALIGNMENT                    32
492
 
493
#define REGNO_OK_FOR_BASE_P(regno)              microblaze_regno_ok_for_base_p ((regno), 1)
494
 
495
#define REGNO_OK_FOR_INDEX_P(regno)             microblaze_regno_ok_for_base_p ((regno), 1)
496
 
497
#ifndef REG_OK_STRICT
498
#define REG_STRICT_FLAG                         0
499
#else
500
#define REG_STRICT_FLAG                         1
501
#endif
502
 
503
#define REG_OK_FOR_BASE_P(X)    \
504
  microblaze_regno_ok_for_base_p (REGNO (X), REG_STRICT_FLAG)
505
 
506
#define REG_OK_FOR_INDEX_P(X)   \
507
  microblaze_regno_ok_for_base_p (REGNO (X), REG_STRICT_FLAG)
508
 
509
#define MAX_REGS_PER_ADDRESS 2
510
 
511
 
512
/* Identify valid constant addresses.  Exclude if PIC addr which
513
   needs scratch register.  */
514
#define CONSTANT_ADDRESS_P(X)                                           \
515
  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF              \
516
    || GET_CODE (X) == CONST_INT                                        \
517
    || (GET_CODE (X) == CONST                                           \
518
        && ! (flag_pic && pic_address_needs_scratch (X))))
519
 
520
/* Define this, so that when PIC, reload won't try to reload invalid
521
   addresses which require two reload registers.  */
522
#define LEGITIMATE_PIC_OPERAND_P(X)  (!pic_address_needs_scratch (X))
523
 
524
#define CASE_VECTOR_MODE                        (SImode)
525
 
526
#ifndef DEFAULT_SIGNED_CHAR
527
#define DEFAULT_SIGNED_CHAR                     1
528
#endif
529
 
530
#define MOVE_MAX                                4
531
#define MAX_MOVE_MAX                            8
532
 
533
#define SLOW_BYTE_ACCESS                        1
534
 
535
/* sCOND operations return 1.  */
536
#define STORE_FLAG_VALUE                        1
537
 
538
#define SHIFT_COUNT_TRUNCATED                   1
539
 
540
/* This results in inefficient code for 64 bit to 32 conversions.
541
   Something needs to be done about this.  Perhaps not use any 32 bit
542
   instructions?  Perhaps use PROMOTE_MODE?  */
543
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC)  1
544
 
545
#define Pmode SImode
546
 
547
#define FUNCTION_MODE   SImode
548
 
549
/* Mode should alwasy be SImode */
550
#define REGISTER_MOVE_COST(MODE, FROM, TO)                      \
551
  ( GR_REG_CLASS_P (FROM) && GR_REG_CLASS_P (TO) ? 2            \
552
   : (FROM) == ST_REGS && GR_REG_CLASS_P (TO) ? 4               \
553
   : 12)
554
 
555
#define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \
556
  (4 + memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
557
 
558
#define BRANCH_COST(speed_p, predictable_p)     2
559
 
560
/* Control the assembler format that we output.  */
561
#define ASM_APP_ON " #APP\n"
562
#define ASM_APP_OFF " #NO_APP\n"
563
 
564
#define REGISTER_NAMES {                                                \
565
  "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",         \
566
  "r8",   "r9",   "r10",  "r11",  "r12",  "r13",  "r14",  "r15",        \
567
  "r16",  "r17",  "r18",  "r19",  "r20",  "r21",  "r22",  "r23",        \
568
  "r24",  "r25",  "r26",  "r27",  "r28",  "r29",  "r30",  "r31",        \
569
  "rmsr", "$ap",  "$rap", "$frp" }
570
 
571
#define ADDITIONAL_REGISTER_NAMES                                       \
572
{                                                                       \
573
  { "r0",        0 + GP_REG_FIRST },                                     \
574
  { "r1",        1 + GP_REG_FIRST },                                    \
575
  { "r2",        2 + GP_REG_FIRST },                                    \
576
  { "r3",        3 + GP_REG_FIRST },                                    \
577
  { "r4",        4 + GP_REG_FIRST },                                    \
578
  { "r5",        5 + GP_REG_FIRST },                                    \
579
  { "r6",        6 + GP_REG_FIRST },                                    \
580
  { "r7",        7 + GP_REG_FIRST },                                    \
581
  { "r8",        8 + GP_REG_FIRST },                                    \
582
  { "r9",        9 + GP_REG_FIRST },                                    \
583
  { "r10",      10 + GP_REG_FIRST },                                    \
584
  { "r11",      11 + GP_REG_FIRST },                                    \
585
  { "r12",      12 + GP_REG_FIRST },                                    \
586
  { "r13",      13 + GP_REG_FIRST },                                    \
587
  { "r14",      14 + GP_REG_FIRST },                                    \
588
  { "r15",      15 + GP_REG_FIRST },                                    \
589
  { "r16",      16 + GP_REG_FIRST },                                    \
590
  { "r17",      17 + GP_REG_FIRST },                                    \
591
  { "r18",      18 + GP_REG_FIRST },                                    \
592
  { "r19",      19 + GP_REG_FIRST },                                    \
593
  { "r20",      20 + GP_REG_FIRST },                                    \
594
  { "r21",      21 + GP_REG_FIRST },                                    \
595
  { "r22",      22 + GP_REG_FIRST },                                    \
596
  { "r23",      23 + GP_REG_FIRST },                                    \
597
  { "r24",      24 + GP_REG_FIRST },                                    \
598
  { "r25",      25 + GP_REG_FIRST },                                    \
599
  { "r26",      26 + GP_REG_FIRST },                                    \
600
  { "r27",      27 + GP_REG_FIRST },                                    \
601
  { "r28",      28 + GP_REG_FIRST },                                    \
602
  { "r29",      29 + GP_REG_FIRST },                                    \
603
  { "r30",      30 + GP_REG_FIRST },                                    \
604
  { "r31",      31 + GP_REG_FIRST },                                    \
605
  { "rmsr",     ST_REG}                                                 \
606
}
607
 
608
#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
609
 
610
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) microblaze_print_operand_punct[CODE]
611
 
612
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
613
 
614
/* ASM_OUTPUT_ALIGNED_COMMON and ASM_OUTPUT_ALIGNED_LOCAL
615
 
616
   Unfortunately, we still need to set the section explicitly. Somehow,
617
   our binutils assign .comm and .lcomm variables to the "current" section
618
   in the assembly file, rather than where they implicitly belong. We need to
619
   remove this explicit setting in GCC when binutils can understand sections
620
   better.  */
621
#undef  ASM_OUTPUT_ALIGNED_COMMON
622
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)              \
623
do {                                                                    \
624
  if ((SIZE) > 0 && (SIZE) <= INT_MAX                                    \
625
      && (int) (SIZE) <= microblaze_section_threshold                   \
626
      && TARGET_XLGPOPT)                                                \
627
    {                                                                   \
628
      switch_to_section (sbss_section);                                 \
629
    }                                                                   \
630
  else                                                                  \
631
    {                                                                   \
632
      switch_to_section (bss_section);                                  \
633
    }                                                                   \
634
  fprintf (FILE, "%s", COMMON_ASM_OP);                                  \
635
  assemble_name ((FILE), (NAME));                                       \
636
  fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",              \
637
           (SIZE), (ALIGN) / BITS_PER_UNIT);                            \
638
  ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");                     \
639
} while (0)
640
 
641
#undef ASM_OUTPUT_ALIGNED_LOCAL
642
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN)               \
643
do {                                                                    \
644
  if ((SIZE) > 0 && (SIZE) <= INT_MAX                                    \
645
      && (int) (SIZE) <= microblaze_section_threshold                   \
646
      && TARGET_XLGPOPT)                                                \
647
    {                                                                   \
648
      switch_to_section (sbss_section);                                 \
649
    }                                                                   \
650
  else                                                                  \
651
    {                                                                   \
652
      switch_to_section (bss_section);                                  \
653
    }                                                                   \
654
  fprintf (FILE, "%s", LCOMMON_ASM_OP);                                 \
655
  assemble_name ((FILE), (NAME));                                       \
656
  fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",              \
657
           (SIZE), (ALIGN) / BITS_PER_UNIT);                            \
658
  ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object");                     \
659
} while (0)
660
 
661
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN)           \
662
do {                                                                    \
663
  ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN);                   \
664
} while (0)
665
 
666
#define ASM_DECLARE_FUNCTION_NAME(STREAM,NAME,DECL)                     \
667
{                                                                       \
668
}
669
 
670
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM)                   \
671
  sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM))
672
 
673
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)                          \
674
  fprintf (STREAM, "\t%s\t%sL%d\n",                                     \
675
           ".gpword",                                                   \
676
           LOCAL_LABEL_PREFIX, VALUE)
677
 
678
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)              \
679
do {                                                                    \
680
  if (flag_pic == 2)                                               \
681
    fprintf (STREAM, "\t%s\t%sL%d@GOTOFF\n",                            \
682
             ".gpword",                                                 \
683
             LOCAL_LABEL_PREFIX, VALUE);                                \
684
  else                                                                  \
685
    fprintf (STREAM, "\t%s\t%sL%d\n",                                   \
686
             ".gpword",                                                 \
687
             LOCAL_LABEL_PREFIX, VALUE);                                \
688
} while (0)
689
 
690
#define ASM_OUTPUT_ALIGN(STREAM,LOG)                                    \
691
  fprintf (STREAM, "\t.align\t%d\n", (LOG))
692
 
693
#define ASM_OUTPUT_SKIP(STREAM,SIZE)                                    \
694
  fprintf (STREAM, "\t.space\t%lu\n", (SIZE))
695
 
696
#define ASCII_DATA_ASM_OP               "\t.ascii\t"
697
#define STRING_ASM_OP                   "\t.asciz\t"
698
 
699
#define ASM_OUTPUT_IDENT(FILE, STRING)                                  \
700
  microblaze_asm_output_ident (FILE, STRING)
701
 
702
/* Default to -G 8 */
703
#ifndef MICROBLAZE_DEFAULT_GVALUE
704
#define MICROBLAZE_DEFAULT_GVALUE 8
705
#endif
706
 
707
/* Given a decl node or constant node, choose the section to output it in
708
   and select that section.  */
709
 
710
/* Store in OUTPUT a string (made with alloca) containing
711
   an assembler-name for a local static variable named NAME.
712
   LABELNO is an integer which is different for each call.  */
713
#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)                  \
714
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10),                    \
715
  sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long)(LABELNO)))
716
 
717
/* How to start an assembler comment.
718
   The leading space is important (the microblaze assembler requires it).  */
719
#ifndef ASM_COMMENT_START
720
#define ASM_COMMENT_START               " #"
721
#endif
722
 
723
#define BSS_VAR         1
724
#define SBSS_VAR        2
725
#define DATA_VAR        4
726
#define SDATA_VAR       5
727
#define RODATA_VAR      6
728
#define SDATA2_VAR      7
729
 
730
/* These definitions are used in with the shift_type flag in the rtl.  */
731
#define SHIFT_CONST     1
732
#define SHIFT_REG       2
733
#define USE_ADDK        3
734
 
735
/* Handle interrupt attribute.  */
736
extern int interrupt_handler;
737
extern int save_volatiles;
738
 
739
#define INTERRUPT_HANDLER_NAME "_interrupt_handler"
740
 
741
/* These #define added for C++.  */
742
#define UNALIGNED_SHORT_ASM_OP          ".data16"
743
#define UNALIGNED_INT_ASM_OP            ".data32"
744
#define UNALIGNED_DOUBLE_INT_ASM_OP     ".data8"
745
 
746
#define ASM_BYTE_OP                     ".data8"
747
 
748
/* The following #defines are used in the headers files. Always retain these.  */
749
 
750
/* Added for declaring size at the end of the function.  */
751
#undef ASM_DECLARE_FUNCTION_SIZE
752
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
753
  do {                                                                  \
754
    if (!flag_inhibit_size_directive)                                   \
755
      {                                                                 \
756
        char label[256];                                                \
757
        static int labelno;                                             \
758
        labelno++;                                                      \
759
        ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno);            \
760
        (*targetm.asm_out.internal_label) (FILE, "Lfe", labelno);       \
761
        fprintf (FILE, "%s", SIZE_ASM_OP);                              \
762
        assemble_name (FILE, (FNAME));                                  \
763
        fprintf (FILE, ",");                                            \
764
        assemble_name (FILE, label);                                    \
765
        fprintf (FILE, "-");                                            \
766
        assemble_name (FILE, (FNAME));                                  \
767
        putc ('\n', FILE);                                              \
768
      }                                                                 \
769
  } while (0)
770
 
771
#define GLOBAL_ASM_OP                   "\t.globl\t"
772
#define TYPE_ASM_OP                     "\t.type\t"
773
#define SIZE_ASM_OP                     "\t.size\t"
774
#define COMMON_ASM_OP                   "\t.comm\t"
775
#define LCOMMON_ASM_OP                  "\t.lcomm\t"
776
 
777
#define MAX_OFILE_ALIGNMENT             (32768*8)
778
 
779
#define TYPE_OPERAND_FMT                "@%s"
780
 
781
/* Write the extra assembler code needed to declare an object properly.  */
782
#undef ASM_DECLARE_OBJECT_NAME
783
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)                       \
784
  do {                                                                  \
785
    fprintf (FILE, "%s", TYPE_ASM_OP);                                  \
786
    assemble_name (FILE, NAME);                                         \
787
    putc (',', FILE);                                                   \
788
    fprintf (FILE, TYPE_OPERAND_FMT, "object");                         \
789
    putc ('\n', FILE);                                                  \
790
    size_directive_output = 0;                                           \
791
    if (!flag_inhibit_size_directive && DECL_SIZE (DECL))               \
792
      {                                                                 \
793
        size_directive_output = 1;                                      \
794
        fprintf (FILE, "%s", SIZE_ASM_OP);                              \
795
        assemble_name (FILE, NAME);                                     \
796
        fprintf (FILE, "," HOST_WIDE_INT_PRINT_DEC "\n",                \
797
        int_size_in_bytes (TREE_TYPE (DECL)));                          \
798
      }                                                                 \
799
    microblaze_declare_object (FILE, NAME, "", ":\n", 0);                        \
800
  } while (0)
801
 
802
#undef ASM_FINISH_DECLARE_OBJECT
803
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)         \
804
do {                                                                     \
805
     const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0);               \
806
     if (!flag_inhibit_size_directive && DECL_SIZE (DECL)                \
807
         && ! AT_END && TOP_LEVEL                                        \
808
         && DECL_INITIAL (DECL) == error_mark_node                       \
809
         && !size_directive_output)                                      \
810
       {                                                                 \
811
         size_directive_output = 1;                                      \
812
         fprintf (FILE, "%s", SIZE_ASM_OP);                              \
813
         assemble_name (FILE, name);                                     \
814
         fprintf (FILE, "," HOST_WIDE_INT_PRINT_DEC "\n",                \
815
                  int_size_in_bytes (TREE_TYPE (DECL)));                 \
816
       }                                                                 \
817
   } while (0)
818
 
819
#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                            \
820
 do { fputc ( '\t', FILE);                                            \
821
      assemble_name (FILE, LABEL1);                                   \
822
      fputs ( " = ", FILE);                                           \
823
      assemble_name (FILE, LABEL2);                                   \
824
      fputc ( '\n', FILE);                                            \
825
 } while (0)
826
 
827
#define ASM_WEAKEN_LABEL(FILE,NAME)                                     \
828
 do { fputs ("\t.weakext\t", FILE);                                     \
829
      assemble_name (FILE, NAME);                                       \
830
      fputc ('\n', FILE);                                               \
831
    } while (0)
832
 
833
#define MAKE_DECL_ONE_ONLY(DECL)        (DECL_WEAK (DECL) = 1)
834
#undef UNIQUE_SECTION_P
835
#define UNIQUE_SECTION_P(DECL)          (DECL_ONE_ONLY (DECL))
836
 
837
#undef TARGET_ASM_NAMED_SECTION
838
#define TARGET_ASM_NAMED_SECTION        default_elf_asm_named_section
839
 
840
/* Define the strings to put out for each section in the object file.
841
 
842
   Note: For ctors/dtors, we want to give these sections the SHF_WRITE
843
   attribute to allow shared libraries to patch/resolve addresses into
844
   these locations.  On Microblaze, there is no concept of shared libraries
845
   yet, so this is for future use.  */
846
#define TEXT_SECTION_ASM_OP     "\t.text"
847
#define DATA_SECTION_ASM_OP     "\t.data"
848
#define READONLY_DATA_SECTION_ASM_OP    \
849
                                "\t.rodata"
850
#define BSS_SECTION_ASM_OP      "\t.bss"
851
#define CTORS_SECTION_ASM_OP    "\t.section\t.ctors,\"aw\""
852
#define DTORS_SECTION_ASM_OP    "\t.section\t.dtors,\"aw\""
853
#define INIT_SECTION_ASM_OP     "\t.section\t.init,\"ax\""
854
#define FINI_SECTION_ASM_OP     "\t.section\t.fini,\"ax\""
855
 
856
#define SDATA_SECTION_ASM_OP    "\t.sdata"      /* Small RW initialized data   */
857
#define SDATA2_SECTION_ASM_OP   "\t.sdata2"     /* Small RO initialized data   */
858
#define SBSS_SECTION_ASM_OP     "\t.sbss"       /* Small RW uninitialized data */
859
#define SBSS2_SECTION_ASM_OP    "\t.sbss2"      /* Small RO uninitialized data */
860
 
861
/* We do this to save a few 10s of code space that would be taken up
862
   by the call_FUNC () wrappers, used by the generic CRT_CALL_STATIC_FUNCTION
863
   definition in crtstuff.c.  */
864
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)      \
865
    asm ( SECTION_OP "\n"                               \
866
          "\tbrlid   r15, " #FUNC "\n\t nop\n"         \
867
          TEXT_SECTION_ASM_OP);
868
 
869
/* We need to group -lm as well, since some Newlib math functions
870
   reference __errno!  */
871
#undef LIB_SPEC
872
#define LIB_SPEC \
873
"%{!nostdlib: \
874
%{pg:-start-group -lxilprofile -lgloss -lxil -lc -lm -end-group } \
875
%{!pg:-start-group -lgloss -lxil -lc -lm -end-group }} "
876
 
877
#undef  ENDFILE_SPEC
878
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
879
 
880
#define STARTFILE_EXECUTABLE_SPEC   "crt0.o%s crti.o%s crtbegin.o%s"
881
#define STARTFILE_XMDSTUB_SPEC      "crt1.o%s crti.o%s crtbegin.o%s"
882
#define STARTFILE_BOOTSTRAP_SPEC    "crt2.o%s crti.o%s crtbegin.o%s"
883
#define STARTFILE_NOVECTORS_SPEC    "crt3.o%s crti.o%s crtbegin.o%s"
884
#define STARTFILE_CRTINIT_SPEC      "%{!pg: %{!mno-clearbss: crtinit.o%s} \
885
%{mno-clearbss: sim-crtinit.o%s}} \
886
%{pg: %{!mno-clearbss: pgcrtinit.o%s} %{mno-clearbss: sim-pgcrtinit.o%s}}"
887
 
888
#define STARTFILE_DEFAULT_SPEC      STARTFILE_EXECUTABLE_SPEC
889
 
890
#undef SUBTARGET_EXTRA_SPECS
891
#define SUBTARGET_EXTRA_SPECS                                           \
892
  { "startfile_executable",     STARTFILE_EXECUTABLE_SPEC },            \
893
  { "startfile_xmdstub",        STARTFILE_XMDSTUB_SPEC },               \
894
  { "startfile_bootstrap",      STARTFILE_BOOTSTRAP_SPEC },             \
895
  { "startfile_novectors",      STARTFILE_NOVECTORS_SPEC },             \
896
  { "startfile_crtinit",        STARTFILE_CRTINIT_SPEC },               \
897
  { "startfile_default",        STARTFILE_DEFAULT_SPEC },
898
 
899
#undef  STARTFILE_SPEC
900
#define STARTFILE_SPEC  "\
901
%{Zxl-mode-executable   : %(startfile_executable)  ; \
902
  mxl-mode-executable   : %(startfile_executable)  ; \
903
  Zxl-mode-xmdstub      : %(startfile_xmdstub)     ; \
904
  mxl-mode-xmdstub      : %(startfile_xmdstub)     ; \
905
  Zxl-mode-bootstrap    : %(startfile_bootstrap)   ; \
906
  mxl-mode-bootstrap    : %(startfile_bootstrap)   ; \
907
  Zxl-mode-novectors    : %(startfile_novectors)   ; \
908
  mxl-mode-novectors    : %(startfile_novectors)   ; \
909
  Zxl-mode-xilkernel    : %(startfile_xilkernel)   ; \
910
  mxl-mode-xilkernel    : %(startfile_xilkernel)   ; \
911
                        : %(startfile_default)       \
912
} \
913
%(startfile_crtinit)"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.