| /* Copyright (C) 2006-2015 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 of the License, 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. |
| |
| 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 */ |
| #define TARGET_CPU_CPP_BUILTINS() spu_cpu_cpp_builtins(pfile) |
| |
| #define C_COMMON_OVERRIDE_OPTIONS spu_c_common_override_options() |
| |
| #define INIT_EXPANDERS spu_init_expanders() |
| |
| /* Which processor to generate code or schedule for. */ |
| enum processor_type |
| { |
| PROCESSOR_CELL, |
| PROCESSOR_CELLEDP |
| }; |
| |
| extern GTY(()) int spu_arch; |
| extern GTY(()) int spu_tune; |
| |
| /* Support for a compile-time default architecture and tuning. The rules are: |
| --with-arch is ignored if -march is specified. |
| --with-tune is ignored if -mtune is specified. */ |
| #define OPTION_DEFAULT_SPECS \ |
| {"arch", "%{!march=*:-march=%(VALUE)}" }, \ |
| {"tune", "%{!mtune=*:-mtune=%(VALUE)}" } |
| |
| /* Default target_flags if no switches specified. */ |
| #ifndef TARGET_DEFAULT |
| #define TARGET_DEFAULT (MASK_ERROR_RELOC | MASK_SAFE_DMA | MASK_BRANCH_HINTS \ |
| | MASK_SAFE_HINTS | MASK_ADDRESS_SPACE_CONVERSION) |
| #endif |
| |
| |
| /* Storage Layout */ |
| |
| #define BITS_BIG_ENDIAN 1 |
| |
| #define BYTES_BIG_ENDIAN 1 |
| |
| #define WORDS_BIG_ENDIAN 1 |
| |
| /* GCC uses word_mode in many places, assuming that it is the fastest |
| integer mode. That is not the case for SPU though. We can't use |
| 32 here because (of some reason I can't remember.) */ |
| #define BITS_PER_WORD 128 |
| |
| #define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT) |
| |
| /* When building libgcc, we need to assume 4 words per units even |
| though UNITS_PER_WORD is 16, because the SPU has basically a 32-bit |
| instruction set although register size is 128 bits. In particular, |
| this causes libgcc to contain __divdi3 instead of __divti3 etc. |
| However, we allow this default to be re-defined on the command |
| line, so that we can use the LIB2_SIDITI_CONV_FUNCS mechanism |
| to get (in addition) TImode versions of some routines. */ |
| #ifndef LIBGCC2_UNITS_PER_WORD |
| #define LIBGCC2_UNITS_PER_WORD 4 |
| #endif |
| |
| #define POINTER_SIZE 32 |
| |
| #define PARM_BOUNDARY 128 |
| |
| #define STACK_BOUNDARY 128 |
| |
| /* We want it 8-byte aligned so we can properly use dual-issue |
| instructions, which can only happen on an 8-byte aligned address. */ |
| #define FUNCTION_BOUNDARY 64 |
| |
| /* We would like to allow a larger alignment for data objects (for DMA) |
| but the aligned attribute is limited by BIGGEST_ALIGNMENT. We don't |
| define BIGGEST_ALIGNMENT as larger because it is used in other places |
| and would end up wasting space. (Is this still true?) */ |
| #define BIGGEST_ALIGNMENT 128 |
| |
| #define MINIMUM_ATOMIC_ALIGNMENT 128 |
| |
| /* Make all static objects 16-byte aligned. This allows us to assume |
| they are also padded to 16-bytes, which means we can use a single |
| load or store instruction to access them. Do the same for objects |
| on the stack. (Except a bug (?) allows some stack objects to be |
| unaligned.) */ |
| #define DATA_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128) |
| #define CONSTANT_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128) |
| #define LOCAL_ALIGNMENT(TYPE,ALIGN) ((ALIGN) > 128 ? (ALIGN) : 128) |
| |
| #define EMPTY_FIELD_BOUNDARY 32 |
| |
| #define STRICT_ALIGNMENT 1 |
| |
| /* symbol_ref's of functions are not aligned to 16 byte boundary. */ |
| #define ALIGNED_SYMBOL_REF_P(X) \ |
| (GET_CODE (X) == SYMBOL_REF \ |
| && (SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1) == 0 \ |
| && (! SYMBOL_REF_FUNCTION_P (X) \ |
| || align_functions >= 16)) |
| |
| #define PCC_BITFIELD_TYPE_MATTERS 1 |
| |
| #define MAX_FIXED_MODE_SIZE 128 |
| |
| #define STACK_SAVEAREA_MODE(save_level) \ |
| (save_level == SAVE_FUNCTION ? VOIDmode \ |
| : save_level == SAVE_NONLOCAL ? SImode \ |
| : Pmode) |
| |
| #define STACK_SIZE_MODE SImode |
| |
| |
| /* Type Layout */ |
| |
| #define INT_TYPE_SIZE 32 |
| |
| #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 STDINT_LONG32 0 |
| |
| |
| /* Register Basics */ |
| |
| /* 128-130 are special registers that never appear in assembly code. */ |
| #define FIRST_PSEUDO_REGISTER 131 |
| |
| #define FIXED_REGISTERS { \ |
| 1, 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, 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, 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, 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, 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, 0, \ |
| 1, 1, 1 \ |
| } |
| |
| #define CALL_USED_REGISTERS { \ |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ |
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ |
| 1, 1, 1, 1, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, \ |
| 1, 1, 1 \ |
| } |
| |
| |
| /* Values in Registers */ |
| |
| #define HARD_REGNO_NREGS(REGNO, MODE) \ |
| ((GET_MODE_BITSIZE(MODE)+MAX_FIXED_MODE_SIZE-1)/MAX_FIXED_MODE_SIZE) |
| |
| #define HARD_REGNO_MODE_OK(REGNO, MODE) 1 |
| |
| #define MODES_TIEABLE_P(MODE1, MODE2) \ |
| (GET_MODE_BITSIZE (MODE1) <= MAX_FIXED_MODE_SIZE \ |
| && GET_MODE_BITSIZE (MODE2) <= MAX_FIXED_MODE_SIZE) |
| |
| |
| /* Register Classes */ |
| |
| 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 { \ |
| {0, 0, 0, 0, 0}, /* no regs */ \ |
| {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}, /* general regs */ \ |
| {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x3}} /* all regs */ |
| |
| #define REGNO_REG_CLASS(REGNO) (GENERAL_REGS) |
| |
| #define BASE_REG_CLASS GENERAL_REGS |
| |
| #define INDEX_REG_CLASS GENERAL_REGS |
| |
| #define REGNO_OK_FOR_BASE_P(regno) \ |
| ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0)) |
| |
| #define REGNO_OK_FOR_INDEX_P(regno) \ |
| ((regno) < FIRST_PSEUDO_REGISTER || (regno > LAST_VIRTUAL_REGISTER && reg_renumber[regno] >= 0)) |
| |
| #define INT_REG_OK_FOR_INDEX_P(X,STRICT) \ |
| ((!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X)))) |
| #define INT_REG_OK_FOR_BASE_P(X,STRICT) \ |
| ((!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X)))) |
| |
| /* GCC assumes that modes are in the lowpart of a register, which is |
| only true for SPU. */ |
| #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ |
| ((GET_MODE_SIZE (FROM) > 4 || GET_MODE_SIZE (TO) > 4) \ |
| && (GET_MODE_SIZE (FROM) < 16 || GET_MODE_SIZE (TO) < 16) \ |
| && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)) |
| |
| #define REGISTER_TARGET_PRAGMAS() do { \ |
| c_register_addr_space ("__ea", ADDR_SPACE_EA); \ |
| targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ |
| }while (0); |
| |
| |
| /* Frame Layout */ |
| |
| #define STACK_GROWS_DOWNWARD |
| |
| #define FRAME_GROWS_DOWNWARD 1 |
| |
| #define STARTING_FRAME_OFFSET (0) |
| |
| #define STACK_POINTER_OFFSET 32 |
| |
| #define FIRST_PARM_OFFSET(FNDECL) (0) |
| |
| #define DYNAMIC_CHAIN_ADDRESS(FP) plus_constant (Pmode, (FP), -16) |
| |
| #define RETURN_ADDR_RTX(COUNT,FP) (spu_return_addr (COUNT, FP)) |
| |
| /* Should this be defined? Would it simplify our implementation. */ |
| /* #define RETURN_ADDR_IN_PREVIOUS_FRAME */ |
| |
| #define INCOMING_RETURN_ADDR_RTX gen_rtx_REG(Pmode, LINK_REGISTER_REGNUM) |
| |
| #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGISTER_REGNUM) |
| |
| #define ARG_POINTER_CFA_OFFSET(FNDECL) \ |
| (crtl->args.pretend_args_size - STACK_POINTER_OFFSET) |
| |
| |
| /* Stack Checking */ |
| |
| /* We store the Available Stack Size in the second slot of the stack |
| register. We emit stack checking code during the prologue. */ |
| #define STACK_CHECK_BUILTIN 1 |
| |
| |
| /* Frame Registers, and other registers */ |
| |
| #define STACK_POINTER_REGNUM 1 |
| |
| /* Will be eliminated. */ |
| #define FRAME_POINTER_REGNUM 128 |
| |
| /* This is not specified in any ABI, so could be set to anything. */ |
| #define HARD_FRAME_POINTER_REGNUM 127 |
| |
| /* Will be eliminated. */ |
| #define ARG_POINTER_REGNUM 129 |
| |
| #define STATIC_CHAIN_REGNUM 2 |
| |
| #define LINK_REGISTER_REGNUM 0 |
| |
| /* Used to keep track of instructions that have clobbered the hint |
| * buffer. Users can also specify it in inline asm. */ |
| #define HBR_REGNUM 130 |
| |
| #define MAX_REGISTER_ARGS 72 |
| #define FIRST_ARG_REGNUM 3 |
| #define LAST_ARG_REGNUM (FIRST_ARG_REGNUM + MAX_REGISTER_ARGS - 1) |
| |
| #define MAX_REGISTER_RETURN 72 |
| #define FIRST_RETURN_REGNUM 3 |
| #define LAST_RETURN_REGNUM (FIRST_RETURN_REGNUM + MAX_REGISTER_RETURN - 1) |
| |
| |
| /* Elimination */ |
| |
| #define ELIMINABLE_REGS \ |
| {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ |
| {ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ |
| {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ |
| {FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} |
| |
| #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ |
| ((OFFSET) = spu_initial_elimination_offset((FROM),(TO))) |
| |
| |
| /* Stack Arguments */ |
| |
| #define ACCUMULATE_OUTGOING_ARGS 1 |
| |
| #define REG_PARM_STACK_SPACE(FNDECL) 0 |
| |
| #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 |
| |
| |
| /* Register Arguments */ |
| |
| #define CUMULATIVE_ARGS int |
| |
| #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \ |
| ((CUM) = 0) |
| |
| /* The SPU ABI wants 32/64-bit types at offset 0 in the quad-word on the |
| stack. 8/16-bit types should be at offsets 3/2 respectively. */ |
| #define FUNCTION_ARG_OFFSET(MODE, TYPE) \ |
| (((TYPE) && INTEGRAL_TYPE_P (TYPE) && GET_MODE_SIZE (MODE) < 4) \ |
| ? (4 - GET_MODE_SIZE (MODE)) \ |
| : 0) |
| |
| #define FUNCTION_ARG_PADDING(MODE,TYPE) upward |
| |
| #define PAD_VARARGS_DOWN 0 |
| |
| #define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM)) |
| |
| /* Scalar Return */ |
| |
| #define FUNCTION_VALUE(VALTYPE, FUNC) \ |
| (spu_function_value((VALTYPE),(FUNC))) |
| |
| #define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_RETURN_REGNUM) |
| |
| #define FUNCTION_VALUE_REGNO_P(N) ((N) >= (FIRST_RETURN_REGNUM) && (N) <= (LAST_RETURN_REGNUM)) |
| |
| |
| /* Machine-specific symbol_ref flags. */ |
| #define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0) |
| |
| /* Aggregate Return */ |
| |
| #define DEFAULT_PCC_STRUCT_RETURN 0 |
| |
| |
| /* Function Entry */ |
| |
| #define EXIT_IGNORE_STACK 0 |
| |
| #define EPILOGUE_USES(REGNO) ((REGNO)==1 ? 1 : 0) |
| |
| |
| /* Profiling */ |
| |
| #define FUNCTION_PROFILER(FILE, LABELNO) \ |
| spu_function_profiler ((FILE), (LABELNO)); |
| |
| #define NO_PROFILE_COUNTERS 1 |
| |
| #define PROFILE_BEFORE_PROLOGUE 1 |
| |
| |
| /* Trampolines */ |
| |
| #define TRAMPOLINE_SIZE (TARGET_LARGE_MEM ? 20 : 16) |
| |
| #define TRAMPOLINE_ALIGNMENT 128 |
| |
| /* Addressing Modes */ |
| |
| #define CONSTANT_ADDRESS_P(X) spu_constant_address_p(X) |
| |
| #define MAX_REGS_PER_ADDRESS 2 |
| |
| #define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \ |
| do { \ |
| rtx new_rtx = spu_legitimize_reload_address (AD, MODE, OPNUM, \ |
| (int)(TYPE)); \ |
| if (new_rtx) \ |
| { \ |
| (AD) = new_rtx; \ |
| goto WIN; \ |
| } \ |
| } while (0) |
| |
| |
| /* Costs */ |
| |
| #define BRANCH_COST(speed_p, predictable_p) spu_branch_cost |
| |
| #define SLOW_BYTE_ACCESS 0 |
| |
| #define MOVE_RATIO(speed) ((speed)? 32 : 4) |
| |
| #define NO_FUNCTION_CSE |
| |
| |
| /* Sections */ |
| |
| #define TEXT_SECTION_ASM_OP ".text" |
| |
| #define DATA_SECTION_ASM_OP ".data" |
| |
| #define JUMP_TABLES_IN_TEXT_SECTION 1 |
| |
| |
| /* PIC */ |
| #define PIC_OFFSET_TABLE_REGNUM 126 |
| |
| |
| /* File Framework */ |
| |
| #define ASM_APP_ON "" |
| |
| #define ASM_APP_OFF "" |
| |
| |
| /* Uninitialized Data */ |
| #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ |
| ( fputs (".comm ", (FILE)), \ |
| assemble_name ((FILE), (NAME)), \ |
| fprintf ((FILE), ",%d\n", (ROUNDED))) |
| |
| #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ |
| ( fputs (".lcomm ", (FILE)), \ |
| assemble_name ((FILE), (NAME)), \ |
| fprintf ((FILE), ",%d\n", (ROUNDED))) |
| |
| |
| /* Label Output */ |
| #define ASM_OUTPUT_LABEL(FILE,NAME) \ |
| do { assemble_name (FILE, NAME); fputs (":\n", FILE); } while (0) |
| |
| #define ASM_OUTPUT_LABELREF(FILE, NAME) \ |
| asm_fprintf (FILE, "%U%s", default_strip_name_encoding (NAME)) |
| |
| #define ASM_OUTPUT_SYMBOL_REF(FILE, X) \ |
| do \ |
| { \ |
| tree decl; \ |
| assemble_name (FILE, XSTR ((X), 0)); \ |
| if ((decl = SYMBOL_REF_DECL ((X))) != 0 \ |
| && TREE_CODE (decl) == VAR_DECL \ |
| && TYPE_ADDR_SPACE (TREE_TYPE (decl))) \ |
| fputs ("@ppu", FILE); \ |
| } while (0) |
| |
| |
| /* Instruction Output */ |
| #define REGISTER_NAMES \ |
| {"$lr", "$sp", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", \ |
| "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31", \ |
| "$32", "$33", "$34", "$35", "$36", "$37", "$38", "$39", "$40", "$41", "$42", "$43", "$44", "$45", "$46", "$47", \ |
| "$48", "$49", "$50", "$51", "$52", "$53", "$54", "$55", "$56", "$57", "$58", "$59", "$60", "$61", "$62", "$63", \ |
| "$64", "$65", "$66", "$67", "$68", "$69", "$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", "$78", "$79", \ |
| "$80", "$81", "$82", "$83", "$84", "$85", "$86", "$87", "$88", "$89", "$90", "$91", "$92", "$93", "$94", "$95", \ |
| "$96", "$97", "$98", "$99", "$100", "$101", "$102", "$103", "$104", "$105", "$106", "$107", "$108", "$109", "$110", "$111", \ |
| "$112", "$113", "$114", "$115", "$116", "$117", "$118", "$119", "$120", "$121", "$122", "$123", "$124", "$125", "$126", "$127", \ |
| "$vfp", "$vap", "hbr" \ |
| } |
| |
| #define PRINT_OPERAND(FILE, X, CODE) print_operand(FILE, X, CODE) |
| |
| #define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ |
| print_operand_address (FILE, ADDR) |
| |
| #define LOCAL_LABEL_PREFIX "." |
| |
| #define USER_LABEL_PREFIX "" |
| |
| #define ASM_COMMENT_START "#" |
| |
| |
| /* Dispatch Tables */ |
| |
| #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ |
| fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL) |
| |
| #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ |
| fprintf (FILE, "\t.word .L%d\n", VALUE) |
| |
| |
| /* Alignment Output */ |
| |
| #define ASM_OUTPUT_ALIGN(FILE,LOG) \ |
| do { if (LOG!=0) fprintf (FILE, "\t.align\t%d\n", (LOG)); } while (0) |
| |
| |
| /* Misc */ |
| |
| #define CASE_VECTOR_MODE SImode |
| |
| #define MOVE_MAX 16 |
| |
| #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) ((INPREC) <= 32 && (OUTPREC) <= (INPREC)) |
| |
| #define STORE_FLAG_VALUE -1 |
| |
| #define Pmode SImode |
| |
| #define FUNCTION_MODE QImode |
| |
| #define NO_IMPLICIT_EXTERN_C 1 |
| |
| |
| /* Address spaces. */ |
| #define ADDR_SPACE_EA 1 |
| |
| |
| /* Builtins. */ |
| |
| enum spu_builtin_type |
| { |
| B_INSN, |
| B_JUMP, |
| B_BISLED, |
| B_CALL, |
| B_HINT, |
| B_OVERLOAD, |
| B_INTERNAL |
| }; |
| |
| struct spu_builtin_description |
| { |
| int fcode; |
| int icode; |
| const char *name; |
| enum spu_builtin_type type; |
| |
| /* The first element of parm is always the return type. The rest |
| are a zero terminated list of parameters. */ |
| int parm[5]; |
| }; |
| |
| extern struct spu_builtin_description spu_builtins[]; |
| |