blob: 0ab436c5f19cd405ec84d731ec467b7cc2ff5507 [file] [log] [blame]
/* tc-nds32.c -- Assemble for the nds32
Copyright (C) 2012-2021 Free Software Foundation, Inc.
Contributed by Andes Technology Corporation.
This file is part of GAS, the GNU Assembler.
GAS 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.
GAS 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 GAS; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#include "as.h"
#include "safe-ctype.h"
#include "subsegs.h"
#include "symcat.h"
#include "dwarf2dbg.h"
#include "dw2gencfi.h"
#include "opcodes/nds32-asm.h"
#include "elf/nds32.h"
#include "bfd/elf32-nds32.h"
#include "hash.h"
#include "sb.h"
#include "macro.h"
#include "opcode/nds32.h"
#include <stdio.h>
#include <errno.h>
#include <limits.h>
/* GAS definitions. */
/* Characters which start a comment. */
const char comment_chars[] = "!";
/* Characters which start a comment when they appear at the start of a line. */
const char line_comment_chars[] = "#!";
/* Characters which separate lines (null and newline are by default). */
const char line_separator_chars[] = ";";
/* Characters which may be used as the exponent character
in a floating point number. */
const char EXP_CHARS[] = "eE";
/* Characters which may be used to indicate a floating point constant. */
const char FLT_CHARS[] = "dDfF";
static int enable_16bit = 1;
/* Save for md_assemble to distinguish if this instruction is
expanded from the pseudo instruction. */
static bool pseudo_opcode = false;
static struct nds32_relocs_pattern *relocs_list = NULL;
/* Save instruction relation to inserting relaxation relocation. */
struct nds32_relocs_pattern
{
segT seg;
fragS *frag;
frchainS *frchain;
symbolS *sym;
fixS* fixP;
struct nds32_opcode *opcode;
char *where;
struct nds32_relocs_pattern *next;
/* Assembled instruction bytes. */
uint32_t insn;
};
/* Suffix name and relocation. */
struct suffix_name
{
const char *suffix;
short unsigned int reloc;
};
static int vec_size = 0;
/* If the assembly code is generated by compiler, it is supposed to have
".flag verbatim" at beginning of the content. We have
'nds32_flag' to parse it and set this field to be non-zero. */
static int verbatim = 0;
static htab_t nds32_gprs_hash;
static htab_t nds32_hint_hash;
#define TLS_REG "$r27"
#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
/* Generate relocation for relax or not, and the default is true. */
static int enable_relax_relocs = 1;
/* Save option -O for performance. */
static int optimize = 0;
/* Save option -Os for code size. */
static int optimize_for_space = 0;
/* Flag to save label exist. */
static int label_exist = 0;
/* Flag to save state in omit_fp region. */
static int in_omit_fp = 0;
/* Tag there is relax relocation having to link. */
static bool relaxing = false;
/* ICT model. */
enum ict_option {
ICT_NONE = 0,
ICT_SMALL,
ICT_LARGE
};
static enum ict_option ict_flag = ICT_NONE;
static htab_t nds32_relax_info_hash;
/* Branch patterns. */
static relax_info_t relax_table[] =
{
{
.opcode = "jal",
.br_range = BR_RANGE_S16M,
.cond_field =
{
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_JAL /* jal label */
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_JAL /* jal label */
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_JAL /* jal label */
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_JAL /* jal label */
},
.relax_code_size[BR_RANGE_S16M] = 4,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JRAL_TA /* jral $ta */
},
.relax_code_size[BR_RANGE_U4G] = 12,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL4},
{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bgezal",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BGEZAL /* bgezal $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BGEZAL /* bgezal $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BGEZAL /* bgezal $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BLTZ, /* bltz $rt, $1 */
INSN_JAL /* jal label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BLTZ, /* bltz $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JRAL_TA /* jral $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bltzal",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BLTZAL /* bltzal $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BLTZAL /* bltzal $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BLTZAL /* bltzal $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BGEZ, /* bgez $rt, $1 */
INSN_JAL /* jal label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BGEZ, /* bgez $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JRAL_TA /* jral $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "j",
.br_range = BR_RANGE_S16M,
.cond_field =
{
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
(INSN_J8 << 16) /* j8 label */
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_J /* j label */
},
. relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S16M] = 4,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_size[BR_RANGE_U4G] = 12,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "j8",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
(INSN_J8 << 16) /* j8 label */
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S16M] = 4,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_size[BR_RANGE_U4G] = 12,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, 0, BFD_RELOC_NDS32_HI20},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP4},
{4, 4, NDS32_HINT | NDS32_FIX, BFD_RELOC_NDS32_LO12S0_ORI},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{8, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{8, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beqz",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
/* We do not use beqz38 and beqzs8 here directly because we
don't want to check register number for specail condition. */
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQZ /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BEQZ /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQZ /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNEZ, /* bnez $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
/* bnez range is 17 pcrel, but it use 15 pcrel here since link time
relaxtion. If 17 pcrel can reach, it do not have to use S16M.
Therefore, 15 pcrel is just for linker to distinguish LONGJUMP5
and LONGJUMP6. */
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNEZ, /* bnez $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bgez",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BGEZ /* bgez $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BGEZ /* bgez $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BGEZ /* bgez $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BLTZ, /* bltz $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BLTZ, /* bltz $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bnez",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNEZ /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BNEZ /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNEZ /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQZ, /* beqz $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQZ, /* beqz $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bgtz",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BGTZ /* bgtz $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BGTZ /* bgtz $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BGTZ /* bgtz $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BLEZ, /* blez $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BLEZ, /* blez $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "blez",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BLEZ /* blez $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BLEZ /* blez $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BLEZ /* blez $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BGTZ, /* bgtz $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BGTZ, /* bgtz $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bltz",
.br_range = BR_RANGE_S64K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BLTZ /* bltz $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BLTZ /* bltz $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BLTZ /* bltz $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BGEZ, /* bgez $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BGEZ, /* bgez $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false},
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beq",
.br_range = BR_RANGE_S16K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQ /* beq $rt, $ra, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BEQ /* beq $rt, $ra, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNE, /* bne $rt, $ra, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNE, /* bne $rt, $ra, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNE, /* bne $rt, $ra, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bne",
.br_range = BR_RANGE_S16K,
.cond_field =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNE /* bne $rt, $ra, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BNE /* bne $rt, $ra, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQ, /* beq $rt, $ra, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQ, /* beq $rt, $ra, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQ, /* beq $rt, $ra, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 15, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beqz38",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQZ38 << 16 /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BEQZ /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQZ /* beqz $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNEZ, /* bnez $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNEZ, /* bnez $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bnez38",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNEZ38 << 16 /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BNEZ /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNEZ /* bnez $rt, label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQZ, /* beqz $rt, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQZ, /* beqz $rt, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beqzs8",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQZS8 << 16 /* beqz $r15, label */
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BEQZ_TA /* beqz $r15, label */
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQZ_TA /* beqz $r15, label */
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNEZ_TA, /* bnez $r15, $1 */
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNEZ_TA, /* bnez $r15, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bnezs8",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNEZS8 << 16 /* bnez $r15, label */
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BNEZ_TA /* bnez $r15, label */
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNEZ_TA /* bnez $r15, label */
},
.relax_code_size[BR_RANGE_S64K] = 4,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQZ_TA, /* beqz $r15, $1 */
INSN_J /* j label */
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQZ_TA, /* beqz $r15, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bnes38",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNES38 << 16 /* bne $rt, $r5, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BNE_R5 /* bne $rt, $r5, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQ_R5, /* beq $rt, $r5, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQ_R5, /* beq $rt, $r5, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQ_R5, /* beq $rt, $r5, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beqs38",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQS38 << 16 /* beq $rt, $r5, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 2,
.relax_branch_isize[BR_RANGE_S256] = 2,
.relax_fixup[BR_RANGE_S256] =
{
{0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_BEQ_R5 /* beq $rt, $r5, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 4,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNE_R5, /* bne $rt, $r5, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNE_R5, /* bne $rt, $r5, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNE_R5, /* bne $rt, $r5, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP6},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{4, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_PTR},
{8, 4, NDS32_FIX | NDS32_HINT, BFD_RELOC_NDS32_LO12S0_ORI},
{8, 4, NDS32_PTR |NDS32_HINT, BFD_RELOC_NDS32_PTR},
{12, 4, NDS32_ABS | NDS32_HINT, BFD_RELOC_NDS32_PTR_RESOLVED},
{12, 4, NDS32_SYM | NDS32_HINT, BFD_RELOC_NDS32_EMPTY},
{12, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "beqc",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7FF, true},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BEQC /* beqc $rt, imm11s, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_MOVI_TA, /* movi $ta, imm11s */
INSN_BEQ_TA /* beq $rt, $ta, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 0, 0xFFFFF, false},
{4, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 8,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BNEC, /* bnec $rt, imm11s, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BNEC, /* bnec $rt, imm11s, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BNEC, /* bnec $rt, imm11s, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
{12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = "bnec",
.br_range = BR_RANGE_S256,
.cond_field =
{
{0, 8, 0x7FF, true},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_seq[BR_RANGE_S256] =
{
INSN_BNEC /* bnec $rt, imm11s, label */
},
.relax_code_condition[BR_RANGE_S256] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S256] = 4,
.relax_branch_isize[BR_RANGE_S256] = 4,
.relax_fixup[BR_RANGE_S256] =
{
{0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16K] =
{
INSN_MOVI_TA, /* movi $ta, imm11s */
INSN_BNE_TA /* bne $rt, $ta, label */
},
.relax_code_condition[BR_RANGE_S16K] =
{
{0, 0, 0xFFFFF, false},
{4, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16K] = 8,
.relax_branch_isize[BR_RANGE_S16K] = 4,
.relax_fixup[BR_RANGE_S16K] =
{
{0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
{0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP7},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S64K] =
{
INSN_BEQC, /* beqc $rt, imm11s, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S64K] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S64K] = 8,
.relax_branch_isize[BR_RANGE_S64K] = 4,
.relax_fixup[BR_RANGE_S64K] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_S16M] =
{
INSN_BEQC, /* beqc $rt, imm11s, $1 */
INSN_J /* j label */
},
.relax_code_condition[BR_RANGE_S16M] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_S16M] = 8,
.relax_branch_isize[BR_RANGE_S16M] = 4,
.relax_fixup[BR_RANGE_S16M] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
{0, 0, 0, 0}
},
.relax_code_seq[BR_RANGE_U4G] =
{
INSN_BEQC, /* beqc $rt, imm11s, $1 */
INSN_SETHI_TA, /* sethi $ta, label */
INSN_ORI_TA, /* ori $ta, $ta, label */
INSN_JR_TA /* jr $ta */
},
.relax_code_condition[BR_RANGE_U4G] =
{
{0, 8, 0x7FF, false},
{0, 20, 0x1F, false},
{0, 0, 0, false}
},
.relax_code_size[BR_RANGE_U4G] = 16,
.relax_branch_isize[BR_RANGE_U4G] = 4,
.relax_fixup[BR_RANGE_U4G] =
{
{0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
{4, 4, 0, BFD_RELOC_NDS32_HI20},
{8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI},
{12, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
{0, 0, 0, 0}
},
},
{
.opcode = NULL,
},
};
/* GAS definitions for command-line options. */
enum options
{
OPTION_BIG = OPTION_MD_BASE,
OPTION_LITTLE,
OPTION_TURBO,
OPTION_PIC,
OPTION_RELAX_FP_AS_GP_OFF,
OPTION_RELAX_B2BB_ON,
OPTION_RELAX_ALL_OFF,
OPTION_OPTIMIZE,
OPTION_OPTIMIZE_SPACE
};
const char *md_shortopts = "m:O:";
struct option md_longopts[] =
{
{"O1", no_argument, NULL, OPTION_OPTIMIZE},
{"Os", no_argument, NULL, OPTION_OPTIMIZE_SPACE},
{"big", no_argument, NULL, OPTION_BIG},
{"little", no_argument, NULL, OPTION_LITTLE},
{"EB", no_argument, NULL, OPTION_BIG},
{"EL", no_argument, NULL, OPTION_LITTLE},
{"meb", no_argument, NULL, OPTION_BIG},
{"mel", no_argument, NULL, OPTION_LITTLE},
{"mall-ext", no_argument, NULL, OPTION_TURBO},
{"mext-all", no_argument, NULL, OPTION_TURBO},
{"mpic", no_argument, NULL, OPTION_PIC},
/* Relaxation related options. */
{"mno-fp-as-gp-relax", no_argument, NULL, OPTION_RELAX_FP_AS_GP_OFF},
{"mb2bb", no_argument, NULL, OPTION_RELAX_B2BB_ON},
{"mno-all-relax", no_argument, NULL, OPTION_RELAX_ALL_OFF},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
struct nds32_parse_option_table
{
const char *name; /* Option string. */
const char *help; /* Help description. */
int (*func) (const char *arg); /* How to parse it. */
};
/* The value `-1' represents this option has *NOT* been set. */
#ifdef NDS32_DEFAULT_ARCH_NAME
static const char* nds32_arch_name = NDS32_DEFAULT_ARCH_NAME;
#else
static const char* nds32_arch_name = "v3";
#endif
static int nds32_baseline = -1;
static int nds32_gpr16 = -1;
static int nds32_fpu_sp_ext = -1;
static int nds32_fpu_dp_ext = -1;
static int nds32_freg = -1;
static int nds32_abi = -1;
/* Record ELF flags */
static int nds32_elf_flags = 0;
static int nds32_fpu_com = 0;
static int nds32_parse_arch (const char *str);
static int nds32_parse_baseline (const char *str);
static int nds32_parse_freg (const char *str);
static int nds32_parse_abi (const char *str);
static void add_mapping_symbol (enum mstate state,
unsigned int padding_byte,
unsigned int align);
static struct nds32_parse_option_table parse_opts [] =
{
{"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
<arch name> could be\n\
v3, v3j, v3m, v3f, v3s, "\
"v2, v2j, v2f, v2s"), nds32_parse_arch},
{"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
<baseline> could be v2, v3, v3m"),
nds32_parse_baseline},
{"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
<freg>\n\
0: 8 SP / 4 DP registers\n\
1: 16 SP / 8 DP registers\n\
2: 32 SP / 16 DP registers\n\
3: 32 SP / 32 DP registers"), nds32_parse_freg},
{"abi=", N_("<abi>\t Specify a abi version\n\
<abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi},
{NULL, NULL, NULL}
};
static int nds32_mac = 1;
static int nds32_div = 1;
static int nds32_16bit_ext = 1;
static int nds32_dx_regs = NDS32_DEFAULT_DX_REGS;
static int nds32_perf_ext = NDS32_DEFAULT_PERF_EXT;
static int nds32_perf_ext2 = NDS32_DEFAULT_PERF_EXT2;
static int nds32_string_ext = NDS32_DEFAULT_STRING_EXT;
static int nds32_audio_ext = NDS32_DEFAULT_AUDIO_EXT;
static int nds32_dsp_ext = NDS32_DEFAULT_DSP_EXT;
static int nds32_zol_ext = NDS32_DEFAULT_ZOL_EXT;
static int nds32_fpu_fma = 0;
static int nds32_pic = 0;
static int nds32_relax_fp_as_gp = 1;
static int nds32_relax_b2bb = 0;
static int nds32_relax_all = 1;
struct nds32_set_option_table
{
const char *name; /* Option string. */
const char *help; /* Help description. */
int *var; /* Variable to be set. */
int value; /* Value to set. */
};
/* The option in this group has both Enable/Disable settings.
Just list on here. */
static struct nds32_set_option_table toggle_opts [] =
{
{"mac", N_("Multiply instructions support"), &nds32_mac, 1},
{"div", N_("Divide instructions support"), &nds32_div, 1},
{"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext, 1},
{"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs, 1},
{"perf-ext", N_("Performance extension"), &nds32_perf_ext, 1},
{"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2, 1},
{"string-ext", N_("String extension"), &nds32_string_ext, 1},
{"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16, 1},
{"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext, 1},
{"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext, 1},
{"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext, 1},
{"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma, 1},
{"dsp-ext", N_("DSP extension"), &nds32_dsp_ext, 1},
{"zol-ext", N_("hardware loop extension"), &nds32_zol_ext, 1},
{NULL, NULL, NULL, 0}
};
/* GAS declarations. */
/* This is the callback for nds32-asm.c to parse operands. */
int
nds32_asm_parse_operand (struct nds32_asm_desc *pdesc,
struct nds32_asm_insn *pinsn,
char **pstr, int64_t *value);
static struct nds32_asm_desc asm_desc;
/* md_after_parse_args ()
GAS will call md_after_parse_args whenever it is defined.
This function checks any conflicting options specified. */
void
nds32_after_parse_args (void)
{
/* If -march option is not used in command-line, set the value of option
variable according to NDS32_DEFAULT_ARCH_NAME. */
nds32_parse_arch (nds32_arch_name);
}
/* This function is called when printing usage message (--help). */
void
md_show_usage (FILE *stream)
{
struct nds32_parse_option_table *coarse_tune;
struct nds32_set_option_table *fine_tune;
fprintf (stream, _("\n NDS32-specific assembler options:\n"));
fprintf (stream, _("\
-O1, Optimize for performance\n\
-Os Optimize for space\n"));
fprintf (stream, _("\
-EL, -mel or -little Produce little endian output\n\
-EB, -meb or -big Produce big endian output\n\
-mpic Generate PIC\n\
-mno-fp-as-gp-relax Suppress fp-as-gp relaxation for this file\n\
-mb2bb-relax Back-to-back branch optimization\n\
-mno-all-relax Suppress all relaxation for this file\n"));
for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
{
if (coarse_tune->help != NULL)
fprintf (stream, _(" -m%s%s\n"),
coarse_tune->name, _(coarse_tune->help));
}
for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
{
if (fine_tune->help != NULL)
fprintf (stream, _(" -m[no-]%-17sEnable/Disable %s\n"),
fine_tune->name, _(fine_tune->help));
}
fprintf (stream, _("\
-mall-ext Turn on all extensions and instructions support\n"));
}
void
nds32_frag_init (fragS *fragp)
{
fragp->tc_frag_data.flag = 0;
fragp->tc_frag_data.opcode = NULL;
fragp->tc_frag_data.fixup = NULL;
}
/* This function reads an expression from a C string and returns a pointer past
the end of the expression. */
static char *
parse_expression (char *str, expressionS *exp)
{
char *s;
char *tmp;
tmp = input_line_pointer; /* Save line pointer. */
input_line_pointer = str;
expression (exp);
s = input_line_pointer;
input_line_pointer = tmp; /* Restore line pointer. */
return s; /* Return pointer to where parsing stopped. */
}
void
nds32_start_line_hook (void)
{
}
/*
* Pseudo opcodes
*/
typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], unsigned int pv);
struct nds32_pseudo_opcode
{
const char *opcode;
int argc;
nds32_pseudo_opcode_func proc;
unsigned int pseudo_val;
/* Some instructions are not pseudo opcode, but they might still be
expanded or changed with other instruction combination for some
conditions. We also apply this structure to assist such work.
For example, if the distance of branch target '.L0' is larger than
imm8s<<1 range,
the instruction:
beqzs8 .L0
will be transformed into:
bnezs8 .LCB0
j .L0
.LCB0:
However, sometimes we do not want assembler to do such changes
because compiler knows how to generate corresponding instruction sequence.
Use this field to indicate that this opcode is also a physical instruction.
If the flag 'verbatim' is nozero and this opcode
is a physical instruction, we should not expand it. */
int physical_op;
};
#define PV_DONT_CARE 0
static htab_t nds32_pseudo_opcode_hash = NULL;
static int
builtin_isreg (const char *s, const char *x ATTRIBUTE_UNUSED)
{
if (s [0] == '$' && str_hash_find (nds32_gprs_hash, (s + 1)))
return 1;
return 0;
}
static int
builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
{
struct nds32_keyword *k;
if (*s != '$')
return -1;
s++;
k = str_hash_find (nds32_gprs_hash, s);
if (k == NULL)
return -1;
return k->value;
}
static int
builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
{
const char *ptr = s;
while (*ptr != '+' && *ptr != '-' && *ptr)
++ptr;
if (*ptr == 0)
return 0;
else
return strtol (ptr, NULL, 0);
}
static void
md_assemblef (const char *format, ...)
{
/* FIXME: hope this is long enough. */
char line[1024];
va_list ap;
unsigned int r;
va_start (ap, format);
r = vsnprintf (line, sizeof (line), format, ap);
md_assemble (line);
gas_assert (r < sizeof (line));
}
/* Some prototypes here, since some op may use another op. */
static void do_pseudo_li_internal (const char *rt, int imm32s);
static void do_pseudo_move_reg_internal (char *dst, char *src);
static void
do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
char *arg_label = argv[0];
relaxing = true;
/* b label */
if (nds32_pic)
{
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
md_assemble ((char *) "add $ta,$ta,$gp");
md_assemble ((char *) "jr $ta");
}
else
{
md_assemblef ("j %s", arg_label);
}
relaxing = false;
}
static void
do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
char *arg_label = argv[0];
relaxing = true;
/* bal|call label */
if (nds32_pic)
{
md_assemblef ("sethi $ta,hi20(%s)", arg_label);
md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
md_assemble ((char *) "add $ta,$ta,$gp");
md_assemble ((char *) "jral $ta");
}
else
{
md_assemblef ("jal %s", arg_label);
}
relaxing = false;
}
static void
do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* rt5, ra5, label */
md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
md_assemblef ("beqz $ta,%s", argv[2]);
}
static void
do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* rt5, ra5, label */
md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
md_assemblef ("beqz $ta,%s", argv[2]);
}
static void
do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* bgt rt5, ra5, label */
md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
md_assemblef ("bnez $ta,%s", argv[2]);
}
static void
do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* bgt rt5, ra5, label */
md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
md_assemblef ("bnez $ta,%s", argv[2]);
}
static void
do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* bgt rt5, ra5, label */
md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
md_assemblef ("beqz $ta,%s", argv[2]);
}
static void
do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* bgt rt5, ra5, label */
md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
md_assemblef ("beqz $ta,%s", argv[2]);
}
static void
do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* rt5, ra5, label */
md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
md_assemblef ("bnez $ta,%s", argv[2]);
}
static void
do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
/* rt5, ra5, label */
md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
md_assemblef ("bnez $ta,%s", argv[2]);
}
static void
do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{
md_assemblef ("jr %s", argv[0]);
}
static void
do_pseudo_bral (int argc, char *argv[],
unsigned int pv ATTRIBUTE_UNUSED)
{