25 changed files with 26524 additions and 46 deletions
File diff suppressed because it is too large
@ -0,0 +1,253 @@ |
|||
/* FR30 opcode support. -*- C -*- |
|||
Copyright 2011 Free Software Foundation, Inc. |
|||
|
|||
Contributed by Red Hat Inc; |
|||
|
|||
This file is part of the GNU Binutils. |
|||
|
|||
This program 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 program 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 this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
MA 02110-1301, USA. */ |
|||
|
|||
/* This file is an addendum to fr30.cpu. Heavy use of C code isn't |
|||
appropriate in .cpu files, so it resides here. This especially applies |
|||
to assembly/disassembly where parsing/printing can be quite involved. |
|||
Such things aren't really part of the specification of the cpu, per se, |
|||
so .cpu files provide the general framework and .opc files handle the |
|||
nitty-gritty details as necessary. |
|||
|
|||
Each section is delimited with start and end markers. |
|||
|
|||
<arch>-opc.h additions use: "-- opc.h" |
|||
<arch>-opc.c additions use: "-- opc.c" |
|||
<arch>-asm.c additions use: "-- asm.c" |
|||
<arch>-dis.c additions use: "-- dis.c" |
|||
<arch>-ibd.h additions use: "-- ibd.h". */ |
|||
|
|||
/* -- opc.h */ |
|||
|
|||
/* ??? This can be improved upon. */ |
|||
#undef CGEN_DIS_HASH_SIZE |
|||
#define CGEN_DIS_HASH_SIZE 16 |
|||
#undef CGEN_DIS_HASH |
|||
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4) |
|||
|
|||
/* -- */ |
|||
|
|||
/* -- asm.c */ |
|||
/* Handle register lists for LDMx and STMx. */ |
|||
|
|||
static int |
|||
parse_register_number (const char **strp) |
|||
{ |
|||
int regno; |
|||
|
|||
if (**strp < '0' || **strp > '9') |
|||
return -1; /* Error. */ |
|||
regno = **strp - '0'; |
|||
++*strp; |
|||
|
|||
if (**strp >= '0' && **strp <= '9') |
|||
{ |
|||
regno = regno * 10 + (**strp - '0'); |
|||
++*strp; |
|||
} |
|||
|
|||
return regno; |
|||
} |
|||
|
|||
static const char * |
|||
parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
const char **strp, |
|||
int opindex ATTRIBUTE_UNUSED, |
|||
unsigned long *valuep, |
|||
int high_low, /* 0 == high, 1 == low. */ |
|||
int load_store) /* 0 == load, 1 == store. */ |
|||
{ |
|||
*valuep = 0; |
|||
while (**strp && **strp != ')') |
|||
{ |
|||
int regno; |
|||
|
|||
if (**strp != 'R' && **strp != 'r') |
|||
break; |
|||
++*strp; |
|||
|
|||
regno = parse_register_number (strp); |
|||
if (regno == -1) |
|||
return _("Register number is not valid"); |
|||
if (regno > 7 && !high_low) |
|||
return _("Register must be between r0 and r7"); |
|||
if (regno < 8 && high_low) |
|||
return _("Register must be between r8 and r15"); |
|||
|
|||
if (high_low) |
|||
regno -= 8; |
|||
|
|||
if (load_store) /* Mask is reversed for store. */ |
|||
*valuep |= 0x80 >> regno; |
|||
else |
|||
*valuep |= 1 << regno; |
|||
|
|||
if (**strp == ',') |
|||
{ |
|||
if (*(*strp + 1) == ')') |
|||
break; |
|||
++*strp; |
|||
} |
|||
} |
|||
|
|||
if (!*strp || **strp != ')') |
|||
return _("Register list is not valid"); |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
static const char * |
|||
parse_low_register_list_ld (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
return parse_register_list (cd, strp, opindex, valuep, |
|||
0 /* Low. */, 0 /* Load. */); |
|||
} |
|||
|
|||
static const char * |
|||
parse_hi_register_list_ld (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
return parse_register_list (cd, strp, opindex, valuep, |
|||
1 /* High. */, 0 /* Load. */); |
|||
} |
|||
|
|||
static const char * |
|||
parse_low_register_list_st (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
return parse_register_list (cd, strp, opindex, valuep, |
|||
0 /* Low. */, 1 /* Store. */); |
|||
} |
|||
|
|||
static const char * |
|||
parse_hi_register_list_st (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
return parse_register_list (cd, strp, opindex, valuep, |
|||
1 /* High. */, 1 /* Store. */); |
|||
} |
|||
|
|||
/* -- */ |
|||
|
|||
/* -- dis.c */ |
|||
static void |
|||
print_register_list (void * dis_info, |
|||
long value, |
|||
long offset, |
|||
int load_store) /* 0 == load, 1 == store. */ |
|||
{ |
|||
disassemble_info *info = dis_info; |
|||
int mask; |
|||
int reg_index = 0; |
|||
char * comma = ""; |
|||
|
|||
if (load_store) |
|||
mask = 0x80; |
|||
else |
|||
mask = 1; |
|||
|
|||
if (value & mask) |
|||
{ |
|||
(*info->fprintf_func) (info->stream, "r%li", reg_index + offset); |
|||
comma = ","; |
|||
} |
|||
|
|||
for (reg_index = 1; reg_index <= 7; ++reg_index) |
|||
{ |
|||
if (load_store) |
|||
mask >>= 1; |
|||
else |
|||
mask <<= 1; |
|||
|
|||
if (value & mask) |
|||
{ |
|||
(*info->fprintf_func) (info->stream, "%sr%li", comma, reg_index + offset); |
|||
comma = ","; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static void |
|||
print_hi_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
print_register_list (dis_info, value, 8, 0 /* Load. */); |
|||
} |
|||
|
|||
static void |
|||
print_low_register_list_ld (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
print_register_list (dis_info, value, 0, 0 /* Load. */); |
|||
} |
|||
|
|||
static void |
|||
print_hi_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
print_register_list (dis_info, value, 8, 1 /* Store. */); |
|||
} |
|||
|
|||
static void |
|||
print_low_register_list_st (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
print_register_list (dis_info, value, 0, 1 /* Store. */); |
|||
} |
|||
|
|||
static void |
|||
print_m4 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
(*info->fprintf_func) (info->stream, "%ld", value); |
|||
} |
|||
/* -- */ |
|||
File diff suppressed because it is too large
@ -0,0 +1,633 @@ |
|||
/* IP2K opcode support. -*- C -*- |
|||
Copyright 2002, 2005, 2011 Free Software Foundation, Inc. |
|||
|
|||
Contributed by Red Hat Inc; |
|||
|
|||
This file is part of the GNU Binutils. |
|||
|
|||
This program 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 program 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 this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
MA 02110-1301, USA. */ |
|||
|
|||
/* |
|||
Each section is delimited with start and end markers. |
|||
|
|||
<arch>-opc.h additions use: "-- opc.h" |
|||
<arch>-opc.c additions use: "-- opc.c" |
|||
<arch>-asm.c additions use: "-- asm.c" |
|||
<arch>-dis.c additions use: "-- dis.c" |
|||
<arch>-ibd.h additions use: "-- ibd.h". */ |
|||
|
|||
/* -- opc.h */ |
|||
|
|||
/* Check applicability of instructions against machines. */ |
|||
#define CGEN_VALIDATE_INSN_SUPPORTED |
|||
|
|||
/* Allows reason codes to be output when assembler errors occur. */ |
|||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS |
|||
|
|||
/* Override disassembly hashing - there are variable bits in the top |
|||
byte of these instructions. */ |
|||
#define CGEN_DIS_HASH_SIZE 8 |
|||
#define CGEN_DIS_HASH(buf, value) \ |
|||
(((* (unsigned char*) (buf)) >> 5) % CGEN_DIS_HASH_SIZE) |
|||
|
|||
#define CGEN_ASM_HASH_SIZE 127 |
|||
#define CGEN_ASM_HASH(insn) ip2k_asm_hash (insn) |
|||
|
|||
extern unsigned int ip2k_asm_hash (const char *); |
|||
extern int ip2k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); |
|||
|
|||
/* -- opc.c */ |
|||
|
|||
#include "safe-ctype.h" |
|||
|
|||
/* A better hash function for instruction mnemonics. */ |
|||
unsigned int |
|||
ip2k_asm_hash (const char* insn) |
|||
{ |
|||
unsigned int hash; |
|||
const char* m = insn; |
|||
|
|||
for (hash = 0; *m && ! ISSPACE (*m); m++) |
|||
hash = (hash * 23) ^ (0x1F & TOLOWER (*m)); |
|||
|
|||
/* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */ |
|||
|
|||
return hash % CGEN_ASM_HASH_SIZE; |
|||
} |
|||
|
|||
|
|||
/* Special check to ensure that instruction exists for given machine. */ |
|||
|
|||
int |
|||
ip2k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) |
|||
{ |
|||
int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); |
|||
|
|||
/* No mach attribute? Assume it's supported for all machs. */ |
|||
if (machs == 0) |
|||
return 1; |
|||
|
|||
return (machs & cd->machs) != 0; |
|||
} |
|||
|
|||
|
|||
/* -- asm.c */ |
|||
|
|||
static const char * |
|||
parse_fr (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
const char *old_strp; |
|||
char *afteroffset; |
|||
enum cgen_parse_operand_result result_type; |
|||
bfd_vma value; |
|||
extern CGEN_KEYWORD ip2k_cgen_opval_register_names; |
|||
bfd_vma tempvalue; |
|||
|
|||
old_strp = *strp; |
|||
afteroffset = NULL; |
|||
|
|||
/* Check here to see if you're about to try parsing a w as the first arg |
|||
and return an error if you are. */ |
|||
if ((strncmp (*strp, "w", 1) == 0) || (strncmp (*strp, "W", 1) == 0)) |
|||
{ |
|||
(*strp)++; |
|||
|
|||
if ((strncmp (*strp, ",", 1) == 0) || ISSPACE (**strp)) |
|||
{ |
|||
/* We've been passed a w. Return with an error message so that |
|||
cgen will try the next parsing option. */ |
|||
errmsg = _("W keyword invalid in FR operand slot."); |
|||
return errmsg; |
|||
} |
|||
*strp = old_strp; |
|||
} |
|||
|
|||
/* Attempt parse as register keyword. */ |
|||
errmsg = cgen_parse_keyword (cd, strp, & ip2k_cgen_opval_register_names, |
|||
(long *) valuep); |
|||
if (*strp != NULL |
|||
&& errmsg == NULL) |
|||
return errmsg; |
|||
|
|||
/* Attempt to parse for "(IP)". */ |
|||
afteroffset = strstr (*strp, "(IP)"); |
|||
|
|||
if (afteroffset == NULL) |
|||
/* Make sure it's not in lower case. */ |
|||
afteroffset = strstr (*strp, "(ip)"); |
|||
|
|||
if (afteroffset != NULL) |
|||
{ |
|||
if (afteroffset != *strp) |
|||
{ |
|||
/* Invalid offset present. */ |
|||
errmsg = _("offset(IP) is not a valid form"); |
|||
return errmsg; |
|||
} |
|||
else |
|||
{ |
|||
*strp += 4; |
|||
*valuep = 0; |
|||
errmsg = NULL; |
|||
return errmsg; |
|||
} |
|||
} |
|||
|
|||
/* Attempt to parse for DP. ex: mov w, offset(DP) |
|||
mov offset(DP),w */ |
|||
|
|||
/* Try parsing it as an address and see what comes back. */ |
|||
afteroffset = strstr (*strp, "(DP)"); |
|||
|
|||
if (afteroffset == NULL) |
|||
/* Maybe it's in lower case. */ |
|||
afteroffset = strstr (*strp, "(dp)"); |
|||
|
|||
if (afteroffset != NULL) |
|||
{ |
|||
if (afteroffset == *strp) |
|||
{ |
|||
/* No offset present. Use 0 by default. */ |
|||
tempvalue = 0; |
|||
errmsg = NULL; |
|||
} |
|||
else |
|||
errmsg = cgen_parse_address (cd, strp, opindex, |
|||
BFD_RELOC_IP2K_FR_OFFSET, |
|||
& result_type, & tempvalue); |
|||
|
|||
if (errmsg == NULL) |
|||
{ |
|||
if (tempvalue <= 127) |
|||
{ |
|||
/* Value is ok. Fix up the first 2 bits and return. */ |
|||
*valuep = 0x0100 | tempvalue; |
|||
*strp += 4; /* Skip over the (DP) in *strp. */ |
|||
return errmsg; |
|||
} |
|||
else |
|||
{ |
|||
/* Found something there in front of (DP) but it's out |
|||
of range. */ |
|||
errmsg = _("(DP) offset out of range."); |
|||
return errmsg; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
/* Attempt to parse for SP. ex: mov w, offset(SP) |
|||
mov offset(SP), w. */ |
|||
afteroffset = strstr (*strp, "(SP)"); |
|||
|
|||
if (afteroffset == NULL) |
|||
/* Maybe it's in lower case. */ |
|||
afteroffset = strstr (*strp, "(sp)"); |
|||
|
|||
if (afteroffset != NULL) |
|||
{ |
|||
if (afteroffset == *strp) |
|||
{ |
|||
/* No offset present. Use 0 by default. */ |
|||
tempvalue = 0; |
|||
errmsg = NULL; |
|||
} |
|||
else |
|||
errmsg = cgen_parse_address (cd, strp, opindex, |
|||
BFD_RELOC_IP2K_FR_OFFSET, |
|||
& result_type, & tempvalue); |
|||
|
|||
if (errmsg == NULL) |
|||
{ |
|||
if (tempvalue <= 127) |
|||
{ |
|||
/* Value is ok. Fix up the first 2 bits and return. */ |
|||
*valuep = 0x0180 | tempvalue; |
|||
*strp += 4; /* Skip over the (SP) in *strp. */ |
|||
return errmsg; |
|||
} |
|||
else |
|||
{ |
|||
/* Found something there in front of (SP) but it's out |
|||
of range. */ |
|||
errmsg = _("(SP) offset out of range."); |
|||
return errmsg; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* Attempt to parse as an address. */ |
|||
*strp = old_strp; |
|||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IP2K_FR9, |
|||
& result_type, & value); |
|||
if (errmsg == NULL) |
|||
{ |
|||
*valuep = value; |
|||
|
|||
/* If a parenthesis is found, warn about invalid form. */ |
|||
if (**strp == '(') |
|||
errmsg = _("illegal use of parentheses"); |
|||
|
|||
/* If a numeric value is specified, ensure that it is between |
|||
1 and 255. */ |
|||
else if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) |
|||
{ |
|||
if (value < 0x1 || value > 0xff) |
|||
errmsg = _("operand out of range (not between 1 and 255)"); |
|||
} |
|||
} |
|||
return errmsg; |
|||
} |
|||
|
|||
static const char * |
|||
parse_addr16 (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result_type; |
|||
bfd_reloc_code_real_type code = BFD_RELOC_NONE; |
|||
bfd_vma value; |
|||
|
|||
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16H) |
|||
code = BFD_RELOC_IP2K_HI8DATA; |
|||
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16L) |
|||
code = BFD_RELOC_IP2K_LO8DATA; |
|||
else |
|||
{ |
|||
/* Something is very wrong. opindex has to be one of the above. */ |
|||
errmsg = _("parse_addr16: invalid opindex."); |
|||
return errmsg; |
|||
} |
|||
|
|||
errmsg = cgen_parse_address (cd, strp, opindex, code, |
|||
& result_type, & value); |
|||
if (errmsg == NULL) |
|||
{ |
|||
/* We either have a relocation or a number now. */ |
|||
if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) |
|||
{ |
|||
/* We got a number back. */ |
|||
if (code == BFD_RELOC_IP2K_HI8DATA) |
|||
value >>= 8; |
|||
else |
|||
/* code = BFD_RELOC_IP2K_LOW8DATA. */ |
|||
value &= 0x00FF; |
|||
} |
|||
*valuep = value; |
|||
} |
|||
|
|||
return errmsg; |
|||
} |
|||
|
|||
static const char * |
|||
parse_addr16_cjp (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result_type; |
|||
bfd_reloc_code_real_type code = BFD_RELOC_NONE; |
|||
bfd_vma value; |
|||
|
|||
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP) |
|||
code = BFD_RELOC_IP2K_ADDR16CJP; |
|||
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P) |
|||
code = BFD_RELOC_IP2K_PAGE3; |
|||
|
|||
errmsg = cgen_parse_address (cd, strp, opindex, code, |
|||
& result_type, & value); |
|||
if (errmsg == NULL) |
|||
{ |
|||
if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) |
|||
{ |
|||
if ((value & 0x1) == 0) /* If the address is even .... */ |
|||
{ |
|||
if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16CJP) |
|||
*valuep = (value >> 1) & 0x1FFF; /* Should mask be 1FFF? */ |
|||
else if (opindex == (CGEN_OPERAND_TYPE) IP2K_OPERAND_ADDR16P) |
|||
*valuep = (value >> 14) & 0x7; |
|||
} |
|||
else |
|||
errmsg = _("Byte address required. - must be even."); |
|||
} |
|||
else if (result_type == CGEN_PARSE_OPERAND_RESULT_QUEUED) |
|||
{ |
|||
/* This will happen for things like (s2-s1) where s2 and s1 |
|||
are labels. */ |
|||
*valuep = value; |
|||
} |
|||
else |
|||
errmsg = _("cgen_parse_address returned a symbol. Literal required."); |
|||
} |
|||
return errmsg; |
|||
} |
|||
|
|||
static const char * |
|||
parse_lit8 (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result_type; |
|||
bfd_reloc_code_real_type code = BFD_RELOC_NONE; |
|||
bfd_vma value; |
|||
|
|||
/* Parse %OP relocating operators. */ |
|||
if (strncmp (*strp, "%bank", 5) == 0) |
|||
{ |
|||
*strp += 5; |
|||
code = BFD_RELOC_IP2K_BANK; |
|||
} |
|||
else if (strncmp (*strp, "%lo8data", 8) == 0) |
|||
{ |
|||
*strp += 8; |
|||
code = BFD_RELOC_IP2K_LO8DATA; |
|||
} |
|||
else if (strncmp (*strp, "%hi8data", 8) == 0) |
|||
{ |
|||
*strp += 8; |
|||
code = BFD_RELOC_IP2K_HI8DATA; |
|||
} |
|||
else if (strncmp (*strp, "%ex8data", 8) == 0) |
|||
{ |
|||
*strp += 8; |
|||
code = BFD_RELOC_IP2K_EX8DATA; |
|||
} |
|||
else if (strncmp (*strp, "%lo8insn", 8) == 0) |
|||
{ |
|||
*strp += 8; |
|||
code = BFD_RELOC_IP2K_LO8INSN; |
|||
} |
|||
else if (strncmp (*strp, "%hi8insn", 8) == 0) |
|||
{ |
|||
*strp += 8; |
|||
code = BFD_RELOC_IP2K_HI8INSN; |
|||
} |
|||
|
|||
/* Parse %op operand. */ |
|||
if (code != BFD_RELOC_NONE) |
|||
{ |
|||
errmsg = cgen_parse_address (cd, strp, opindex, code, |
|||
& result_type, & value); |
|||
if ((errmsg == NULL) && |
|||
(result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)) |
|||
errmsg = _("percent-operator operand is not a symbol"); |
|||
|
|||
*valuep = value; |
|||
} |
|||
/* Parse as a number. */ |
|||
else |
|||
{ |
|||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep); |
|||
|
|||
/* Truncate to eight bits to accept both signed and unsigned input. */ |
|||
if (errmsg == NULL) |
|||
*valuep &= 0xFF; |
|||
} |
|||
|
|||
return errmsg; |
|||
} |
|||
|
|||
static const char * |
|||
parse_bit3 (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
char mode = 0; |
|||
long count = 0; |
|||
unsigned long value; |
|||
|
|||
if (strncmp (*strp, "%bit", 4) == 0) |
|||
{ |
|||
*strp += 4; |
|||
mode = 1; |
|||
} |
|||
else if (strncmp (*strp, "%msbbit", 7) == 0) |
|||
{ |
|||
*strp += 7; |
|||
mode = 1; |
|||
} |
|||
else if (strncmp (*strp, "%lsbbit", 7) == 0) |
|||
{ |
|||
*strp += 7; |
|||
mode = 2; |
|||
} |
|||
|
|||
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); |
|||
if (errmsg) |
|||
return errmsg; |
|||
|
|||
if (mode) |
|||
{ |
|||
value = * valuep; |
|||
if (value == 0) |
|||
{ |
|||
errmsg = _("Attempt to find bit index of 0"); |
|||
return errmsg; |
|||
} |
|||
|
|||
if (mode == 1) |
|||
{ |
|||
count = 31; |
|||
while ((value & 0x80000000) == 0) |
|||
{ |
|||
count--; |
|||
value <<= 1; |
|||
} |
|||
} |
|||
else if (mode == 2) |
|||
{ |
|||
count = 0; |
|||
while ((value & 0x00000001) == 0) |
|||
{ |
|||
count++; |
|||
value >>= 1; |
|||
} |
|||
} |
|||
|
|||
*valuep = count; |
|||
} |
|||
|
|||
return errmsg; |
|||
} |
|||
|
|||
/* -- dis.c */ |
|||
|
|||
static void |
|||
print_fr (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
const CGEN_KEYWORD_ENTRY *ke; |
|||
extern CGEN_KEYWORD ip2k_cgen_opval_register_names; |
|||
long offsettest; |
|||
long offsetvalue; |
|||
|
|||
if (value == 0) /* This is (IP). */ |
|||
{ |
|||
(*info->fprintf_func) (info->stream, "%s", "(IP)"); |
|||
return; |
|||
} |
|||
|
|||
offsettest = value >> 7; |
|||
offsetvalue = value & 0x7F; |
|||
|
|||
/* Check to see if first two bits are 10 -> (DP). */ |
|||
if (offsettest == 2) |
|||
{ |
|||
if (offsetvalue == 0) |
|||
(*info->fprintf_func) (info->stream, "%s","(DP)"); |
|||
else |
|||
(*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue, "(DP)"); |
|||
return; |
|||
} |
|||
|
|||
/* Check to see if first two bits are 11 -> (SP). */ |
|||
if (offsettest == 3) |
|||
{ |
|||
if (offsetvalue == 0) |
|||
(*info->fprintf_func) (info->stream, "%s", "(SP)"); |
|||
else |
|||
(*info->fprintf_func) (info->stream, "$%lx%s", offsetvalue,"(SP)"); |
|||
return; |
|||
} |
|||
|
|||
/* Attempt to print as a register keyword. */ |
|||
ke = cgen_keyword_lookup_value (& ip2k_cgen_opval_register_names, value); |
|||
|
|||
if (ke != NULL) |
|||
(*info->fprintf_func) (info->stream, "%s", ke->name); |
|||
else |
|||
/* Print as an address literal. */ |
|||
(*info->fprintf_func) (info->stream, "$%02lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
(*info->fprintf_func) (info->stream, "$%lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex8 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
(*info->fprintf_func) (info->stream, "$%02lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex_addr16h (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
/* This is a loadh instruction. Shift the value to the left |
|||
by 8 bits so that disassembled code will reassemble properly. */ |
|||
value = ((value << 8) & 0xFF00); |
|||
|
|||
(*info->fprintf_func) (info->stream, "$%04lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex_addr16l (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
(*info->fprintf_func) (info->stream, "$%04lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex_p (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
value = ((value << 14) & 0x1C000); |
|||
;value = (value & 0x1FFFF); |
|||
(*info->fprintf_func) (info->stream, "$%05lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_dollarhex_cj (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
value = ((value << 1) & 0x1FFFF); |
|||
(*info->fprintf_func) (info->stream, "$%05lx", value); |
|||
} |
|||
|
|||
static void |
|||
print_decimal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, |
|||
void * dis_info, |
|||
long value, |
|||
unsigned int attrs ATTRIBUTE_UNUSED, |
|||
bfd_vma pc ATTRIBUTE_UNUSED, |
|||
int length ATTRIBUTE_UNUSED) |
|||
{ |
|||
disassemble_info *info = (disassemble_info *) dis_info; |
|||
|
|||
(*info->fprintf_func) (info->stream, "%ld", value); |
|||
} |
|||
|
|||
|
|||
|
|||
/* -- */ |
|||
|
|||
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,281 @@ |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
; Insns introduced for the MeP-c5 core |
|||
; |
|||
|
|||
(dnf f-c5n4 "extended field" (all-mep-core-isas) 16 4) |
|||
(dnf f-c5n5 "extended field" (all-mep-core-isas) 20 4) |
|||
(dnf f-c5n6 "extended field" (all-mep-core-isas) 24 4) |
|||
(dnf f-c5n7 "extended field" (all-mep-core-isas) 28 4) |
|||
(dnf f-rl5 "register l c5" (all-mep-core-isas) 20 4) |
|||
(df f-12s20 "extended field" (all-mep-core-isas) 20 12 INT #f #f) |
|||
|
|||
(dnop rl5 "register Rl c5" (all-mep-core-isas) h-gpr f-rl5) |
|||
(dnop cdisp12 "copro addend (12 bits)" (all-mep-core-isas) h-sint f-12s20) |
|||
|
|||
(dnci stcb_r "store in control bus space" (VOLATILE (MACH c5)) |
|||
"stcb $rn,($rma)" |
|||
(+ MAJ_7 rn rma (f-sub4 12)) |
|||
(c-call VOID "do_stcb" rn (and rma #xffff)) |
|||
((mep (unit u-use-gpr (in usereg rn)) |
|||
(unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec) |
|||
(unit u-stcb)))) |
|||
|
|||
(dnci ldcb_r "load from control bus space" (VOLATILE (MACH c5) (LATENCY 3)) |
|||
"ldcb $rn,($rma)" |
|||
(+ MAJ_7 rn rma (f-sub4 13)) |
|||
(set rn (c-call SI "do_ldcb" (and rma #xffff))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-ldcb) |
|||
(unit u-exec) |
|||
(unit u-ldcb-gpr (out loadreg rn))))) |
|||
|
|||
(dnci pref "cache prefetch" ((MACH c5) VOLATILE) |
|||
"pref $cimm4,($rma)" |
|||
(+ MAJ_7 cimm4 rma (f-sub4 5)) |
|||
(sequence () |
|||
(c-call VOID "check_option_dcache" pc) |
|||
(c-call VOID "do_cache_prefetch" cimm4 rma pc)) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci prefd "cache prefetch" ((MACH c5) VOLATILE) |
|||
"pref $cimm4,$sdisp16($rma)" |
|||
(+ MAJ_15 cimm4 rma (f-sub4 3) sdisp16) |
|||
(sequence () |
|||
(c-call VOID "check_option_dcache" pc) |
|||
(c-call VOID "do_cache_prefetch" cimm4 (add INT rma (ext SI sdisp16)) pc)) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci casb3 "compare and swap byte 3" ((MACH c5) VOLATILE OPTIONAL_BIT_INSN) |
|||
"casb3 $rl5,$rn,($rm)" |
|||
(+ MAJ_15 rn rm (f-sub4 #x1) (f-c5n4 #x2) rl5 (f-c5n6 #x0) (f-c5n7 #x0)) |
|||
(sequence () |
|||
(c-call VOID "do_casb3" (index-of rl5) rn rm pc) |
|||
(set rl5 rl5) |
|||
) |
|||
((mep (unit u-use-gpr (in usereg rl5)) |
|||
(unit u-load-gpr (out loadreg rl5)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci cash3 "compare and swap halfword 3" ((MACH c5) VOLATILE OPTIONAL_BIT_INSN) |
|||
"cash3 $rl5,$rn,($rm)" |
|||
(+ MAJ_15 rn rm (f-sub4 #x1) (f-c5n4 #x2) rl5 (f-c5n6 #x0) (f-c5n7 #x1)) |
|||
(sequence () |
|||
(c-call VOID "do_cash3" (index-of rl5) rn rm pc) |
|||
(set rl5 rl5) |
|||
) |
|||
((mep (unit u-use-gpr (in usereg rl5)) |
|||
(unit u-load-gpr (out loadreg rl5)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci casw3 "compare and swap word 3" ((MACH c5) VOLATILE OPTIONAL_BIT_INSN) |
|||
"casw3 $rl5,$rn,($rm)" |
|||
(+ MAJ_15 rn rm (f-sub4 #x1) (f-c5n4 #x2) rl5 (f-c5n6 #x0) (f-c5n7 #x2)) |
|||
(sequence () |
|||
(c-call VOID "do_casw3" (index-of rl5) rn rm pc) |
|||
(set rl5 rl5) |
|||
) |
|||
((mep (unit u-use-gpr (in usereg rl5)) |
|||
(unit u-load-gpr (out loadreg rl5)) |
|||
(unit u-exec)))) |
|||
|
|||
|
|||
|
|||
(dnci sbcp "store byte coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"sbcp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 0) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(c-call VOID "check_write_to_text" (add rma (ext SI cdisp12))) |
|||
(set (mem QI (add rma (ext SI cdisp12))) (and crn #xff))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lbcp "load byte coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"lbcp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 4) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (ext SI (mem QI (add rma (ext SI cdisp12)))))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lbucp "load byte coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"lbucp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 12) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem QI (add rma (ext SI cdisp12)))))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
|
|||
(dnci shcp "store half-word coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"shcp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 1) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(c-call VOID "check_write_to_text" (add rma (ext SI cdisp12))) |
|||
(set (mem HI (add rma (ext SI cdisp12))) (and crn #xffff))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lhcp "load half-word coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"lhcp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 5) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (ext SI (mem HI (add rma (ext SI cdisp12)))))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lhucp "load half-word coprocessor" (OPTIONAL_CP_INSN (STALL STORE) (MACH c5)) |
|||
"lhucp $crn,$cdisp12($rma)" |
|||
(+ MAJ_15 crn rma (f-sub4 6) (f-ext4 13) cdisp12) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem HI (add rma (ext SI cdisp12)))))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
|
|||
(dnci lbucpa "load byte coprocessor" (OPTIONAL_CP_INSN (STALL LOAD) (MACH c5)) |
|||
"lbucpa $crn,($rma+),$cdisp10" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xC) (f-ext62 #x0) cdisp10) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem QI rma))) |
|||
(set rma (add rma cdisp10))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lhucpa "load half-word coprocessor" (OPTIONAL_CP_INSN (STALL LOAD) (MACH c5)) |
|||
"lhucpa $crn,($rma+),$cdisp10a2" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xD) (f-ext62 #x0) cdisp10a2) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem HI (and rma (inv SI 1))))) |
|||
(set rma (add rma (ext SI cdisp10a2)))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lbucpm0 "lbucpm0" (OPTIONAL_CP_INSN (MACH c5)) |
|||
"lbucpm0 $crn,($rma+),$cdisp10" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xc) (f-ext62 #x2) cdisp10) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem QI rma))) |
|||
(set rma (mod0 cdisp10))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lhucpm0 "lhucpm0" (OPTIONAL_CP_INSN (MACH c5)) |
|||
"lhucpm0 $crn,($rma+),$cdisp10a2" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xd) (f-ext62 #x2) cdisp10a2) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem HI (and rma (inv SI 1))))) |
|||
(set rma (mod0 cdisp10a2))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lbucpm1 "lbucpm1" (OPTIONAL_CP_INSN (MACH c5)) |
|||
"lbucpm1 $crn,($rma+),$cdisp10" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xc) (f-ext62 #x3) cdisp10) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem QI rma))) |
|||
(set rma (mod1 cdisp10))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci lhucpm1 "lhucpm1" (OPTIONAL_CP_INSN (MACH c5)) |
|||
"lhucpm1 $crn,($rma+),$cdisp10a2" |
|||
(+ MAJ_15 crn rma (f-sub4 5) (f-ext4 #xd) (f-ext62 #x3) cdisp10a2) |
|||
(sequence () |
|||
(c-call "check_option_cp" pc) |
|||
(set crn (zext SI (mem HI (and rma (inv SI 1))))) |
|||
(set rma (mod1 cdisp10a2))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci uci "uci" ((MACH c5) VOLATILE) |
|||
"uci $rn,$rm,$uimm16" |
|||
(+ MAJ_15 rn rm (f-sub4 2) simm16) |
|||
(set rn (c-call SI "do_UCI" rn rm (zext SI uimm16) pc)) |
|||
((mep (unit u-use-gpr (in usereg rm)) |
|||
(unit u-use-gpr (in usereg rn)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnf f-c5-rnm "register n/m" (all-mep-isas) 4 8) |
|||
(dnf f-c5-rm "register m" (all-mep-isas) 8 4) |
|||
(df f-c5-16u16 "general 16-bit u-val" (all-mep-isas) 16 16 UINT #f #f) |
|||
|
|||
(dnmf f-c5-rmuimm20 "20-bit immediate in Rm/Imm16" (all-mep-isas) UINT |
|||
(f-c5-rm f-c5-16u16) |
|||
(sequence () ; insert |
|||
(set (ifield f-c5-rm) (srl (ifield f-c5-rmuimm20) 16)) |
|||
(set (ifield f-c5-16u16) (and (ifield f-c5-rmuimm20) #xffff)) |
|||
) |
|||
(sequence () ; extract |
|||
(set (ifield f-c5-rmuimm20) (or (ifield f-c5-16u16) |
|||
(sll (ifield f-c5-rm) 16))) |
|||
) |
|||
) |
|||
(dnop c5rmuimm20 "20-bit immediate in rm and imm16" (all-mep-core-isas) h-uint f-c5-rmuimm20) |
|||
|
|||
(dnmf f-c5-rnmuimm24 "24-bit immediate in Rm/Imm16" (all-mep-isas) UINT |
|||
(f-c5-rnm f-c5-16u16) |
|||
(sequence () ; insert |
|||
(set (ifield f-c5-rnm) (srl (ifield f-c5-rnmuimm24) 16)) |
|||
(set (ifield f-c5-16u16) (and (ifield f-c5-rnmuimm24) #xffff)) |
|||
) |
|||
(sequence () ; extract |
|||
(set (ifield f-c5-rnmuimm24) (or (ifield f-c5-16u16) |
|||
(sll (ifield f-c5-rnm) 16))) |
|||
) |
|||
) |
|||
(dnop c5rnmuimm24 "24-bit immediate in rn, rm, and imm16" (all-mep-core-isas) h-uint f-c5-rnmuimm24) |
|||
|
|||
(dnci dsp "dsp" ((MACH c5) VOLATILE) |
|||
"dsp $rn,$rm,$uimm16" |
|||
(+ MAJ_15 rn rm (f-sub4 0) uimm16) |
|||
(set rn (c-call SI "do_DSP" rn rm (zext SI uimm16) pc)) |
|||
((mep (unit u-use-gpr (in usereg rm)) |
|||
(unit u-use-gpr (in usereg rn)) |
|||
(unit u-exec)))) |
|||
|
|||
(dnci dsp0 "dsp0" ((MACH c5) VOLATILE NO-DIS ALIAS) |
|||
"dsp0 $c5rnmuimm24" |
|||
(+ MAJ_15 c5rnmuimm24 (f-sub4 0)) |
|||
(c-call VOID "do_DSP" (zext SI c5rnmuimm24) pc) |
|||
((mep (unit u-exec)))) |
|||
|
|||
(dnci dsp1 "dsp1" ((MACH c5) VOLATILE NO-DIS ALIAS) |
|||
"dsp1 $rn,$c5rmuimm20" |
|||
(+ MAJ_15 rn (f-sub4 0) c5rmuimm20) |
|||
(set rn (c-call SI "do_DSP" rn (zext SI c5rmuimm20) pc)) |
|||
((mep (unit u-use-gpr (in usereg rn)) |
|||
(unit u-exec)))) |
|||
File diff suppressed because it is too large
@ -0,0 +1,27 @@ |
|||
; Toshiba MeP Media Engine architecture description. -*- Scheme -*- |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
; This file serves as a wrapper to bring in the core description plus |
|||
; sample implementations of the UCI and DSP instructions. |
|||
|
|||
(include "mep-core.cpu") |
|||
(include "mep-ext-cop.cpu") |
|||
@ -0,0 +1,25 @@ |
|||
; Toshiba MeP Media Engine architecture description. -*- Scheme -*- |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
;; begin-user-isa-includes |
|||
(include "mep-ivc2.cpu") |
|||
;; end-user-isa-includes |
|||
@ -0,0 +1,340 @@ |
|||
; Toshiba MeP FMAX Coprocessor description. -*- Scheme -*- |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; MeP-Integrator will redefine the isa pmacros below to allow the bit widths |
|||
; specified below for each ME_MODULE using this coprocessor. |
|||
; This coprocessor requires only the 32 bit insns in the core. |
|||
;------------------------------------------------------------------------------ |
|||
; begin-isas |
|||
(define-pmacro fmax-core-isa () (ISA ext_core2)) |
|||
(define-pmacro all-fmax-isas () (ISA ext_core2)) |
|||
; end-isas |
|||
|
|||
;****************************************************************************** |
|||
; ifields |
|||
;------------------------------------------------------------------------------ |
|||
; opcodes |
|||
(dnf f-fmax-0-4 "opcode" (all-fmax-isas) 0 4) |
|||
(dnf f-fmax-4-4 "opcode" (all-fmax-isas) 4 4) |
|||
(dnf f-fmax-8-4 "opcode" (all-fmax-isas) 8 4) |
|||
(dnf f-fmax-12-4 "opcode" (all-fmax-isas) 12 4) |
|||
(dnf f-fmax-16-4 "opcode" (all-fmax-isas) 16 4) |
|||
(dnf f-fmax-20-4 "opcode" (all-fmax-isas) 20 4) |
|||
(dnf f-fmax-24-4 "opcode" (all-fmax-isas) 24 4) |
|||
(dnf f-fmax-28-1 "opcode" (all-fmax-isas) 28 1) |
|||
(dnf f-fmax-29-1 "opcode" (all-fmax-isas) 29 1) |
|||
(dnf f-fmax-30-1 "opcode" (all-fmax-isas) 30 1) |
|||
(dnf f-fmax-31-1 "opcode" (all-fmax-isas) 31 1) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; FR registers |
|||
(define-multi-ifield |
|||
(name f-fmax-frd) |
|||
(comment "FRd register") |
|||
(attrs all-fmax-isas) |
|||
(mode UINT) |
|||
(subfields f-fmax-28-1 f-fmax-4-4) |
|||
(insert (sequence () |
|||
(set (ifield f-fmax-4-4) (and (ifield f-fmax-frd) #xf)) |
|||
(set (ifield f-fmax-28-1) (srl (ifield f-fmax-frd) 4)))) |
|||
(extract (set (ifield f-fmax-frd) |
|||
(or (sll (ifield f-fmax-28-1) 4) (ifield f-fmax-4-4)))) |
|||
) |
|||
(define-multi-ifield |
|||
(name f-fmax-frn) |
|||
(comment "FRn register") |
|||
(attrs all-fmax-isas) |
|||
(mode UINT) |
|||
(subfields f-fmax-29-1 f-fmax-20-4) |
|||
(insert (sequence () |
|||
(set (ifield f-fmax-20-4) (and (ifield f-fmax-frn) #xf)) |
|||
(set (ifield f-fmax-29-1) (srl (ifield f-fmax-frn) 4)))) |
|||
(extract (set (ifield f-fmax-frn) |
|||
(or (sll (ifield f-fmax-29-1) 4) (ifield f-fmax-20-4)))) |
|||
) |
|||
(define-multi-ifield |
|||
(name f-fmax-frm) |
|||
(comment "FRm register") |
|||
(attrs all-fmax-isas) |
|||
(mode UINT) |
|||
(subfields f-fmax-30-1 f-fmax-24-4) |
|||
(insert (sequence () |
|||
(set (ifield f-fmax-24-4) (and (ifield f-fmax-frm) #xf)) |
|||
(set (ifield f-fmax-30-1) (srl (ifield f-fmax-frm) 4)))) |
|||
(extract (set (ifield f-fmax-frm) |
|||
(or (sll (ifield f-fmax-30-1) 4) (ifield f-fmax-24-4)))) |
|||
) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Core General registers |
|||
(dnf f-fmax-rm "opcode" (all-fmax-isas) 8 4) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Condition opcodes enum |
|||
(define-normal-insn-enum fmax-cond "condition opcode enum" (all-fmax-isas) FMAX_ f-fmax-8-4 |
|||
("f" "u" "e" "ue" "l" "ul" "le" "ule" |
|||
"fi" "ui" "ei" "uei" "li" "uli" "lei" "ulei") |
|||
) |
|||
|
|||
;****************************************************************************** |
|||
; Hardware |
|||
;------------------------------------------------------------------------------ |
|||
; FR registers |
|||
|
|||
; Given a coprocessor register number N, expand to a |
|||
; name/index pair: ($frN N) |
|||
(define-pmacro (-fmax-fr-reg-pair n) ((.sym "fr" n) n)) |
|||
(define-pmacro (-fmax-cr-reg-pair n) ((.sym "c" n) n)) |
|||
|
|||
; NOTE: This exists solely for the purpose of providing the proper register names for this coprocessor. |
|||
; GDB will use the hardware table generated from this declaration. The operands use h-cr |
|||
; from mep-core.cpu so that SID's semantic trace will be consistent between |
|||
; the core and the coprocessor but use parse/print handlers which reference the hardware table |
|||
; generated from this declarations |
|||
(define-hardware |
|||
(name h-cr-fmax) |
|||
(comment "Floating point registers") |
|||
(attrs all-fmax-isas VIRTUAL IS_FLOAT) |
|||
(type register SF (32)) |
|||
(indices keyword "$" |
|||
(.splice (.unsplice (.map -fmax-fr-reg-pair (.iota 32))) |
|||
(.unsplice (.map -fmax-cr-reg-pair (.iota 32)))) |
|||
) |
|||
(get (index) (c-call SF "fmax_fr_get_handler" index)) |
|||
(set (index newval) (c-call VOID "fmax_fr_set_handler" index newval)) |
|||
) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Control registers |
|||
; NOTE: This exists solely for the purpose of providing the proper register names for this coprocessor. |
|||
; GDB will use the hardware table generated from this declaration. The operands use h-ccr |
|||
; from mep-core.cpu so that SID's semantic trace will be consistent between |
|||
; the core and the coprocessor but use parse/print handlers which reference the hardware table |
|||
; generated from this declarations |
|||
(define-hardware |
|||
(name h-ccr-fmax) |
|||
(comment "Coprocessor Identifier and Revision Register") |
|||
(attrs all-fmax-isas VIRTUAL) |
|||
(type register USI (16)) |
|||
(indices keyword "$" ( |
|||
("cirr" 0) ("fcr0" 0) ("ccr0" 0) |
|||
("cbcr" 1) ("fcr1" 1) ("ccr1" 1) |
|||
("cerr" 15) ("fcr15" 15) ("ccr15" 15) |
|||
) |
|||
) |
|||
(set (index newval) (c-call VOID "h_ccr_set" index newval)) |
|||
(get (index) (c-call SI "h_ccr_get" index)) |
|||
) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Misc |
|||
(define-hardware |
|||
(name h-fmax-compare-i-p) |
|||
(comment "flag") |
|||
(attrs all-fmax-isas) |
|||
(type register USI) |
|||
) |
|||
|
|||
;****************************************************************************** |
|||
; Operands |
|||
;------------------------------------------------------------------------------ |
|||
; FR Registers |
|||
(define-full-operand fmax-FRd "FRd" (all-fmax-isas (CDATA FMAX_FLOAT)) h-cr SF f-fmax-frd ((parse "fmax_cr") (print "fmax_cr")) () ()) |
|||
(define-full-operand fmax-FRn "FRn" (all-fmax-isas (CDATA FMAX_FLOAT)) h-cr SF f-fmax-frn ((parse "fmax_cr") (print "fmax_cr")) () ()) |
|||
(define-full-operand fmax-FRm "FRm" (all-fmax-isas (CDATA FMAX_FLOAT)) h-cr SF f-fmax-frm ((parse "fmax_cr") (print "fmax_cr")) () ()) |
|||
|
|||
(define-full-operand fmax-FRd-int "FRd as an integer" (all-fmax-isas (CDATA FMAX_INT)) h-cr SI f-fmax-frd ((parse "fmax_cr") (print "fmax_cr")) () ()) |
|||
(define-full-operand fmax-FRn-int "FRn as an integer" (all-fmax-isas (CDATA FMAX_INT)) h-cr SI f-fmax-frn ((parse "fmax_cr") (print "fmax_cr")) () ()) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Control registers |
|||
(define-full-operand fmax-CCRn "CCRn" (all-fmax-isas (CDATA REGNUM)) h-ccr DFLT f-fmax-4-4 ((parse "fmax_ccr") (print "fmax_ccr")) () ()) |
|||
|
|||
(dnop fmax-CIRR "CIRR" (all-fmax-isas SEM-ONLY) h-ccr 0) |
|||
(dnop fmax-CBCR "CBCR" (all-fmax-isas SEM-ONLY) h-ccr 1) |
|||
(dnop fmax-CERR "CERR" (all-fmax-isas SEM-ONLY) h-ccr 15) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Core General Registers |
|||
(dnop fmax-Rm "Rm" (all-fmax-isas) h-gpr f-fmax-rm) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; misc |
|||
(dnop fmax-Compare-i-p "flag" (all-fmax-isas SEM-ONLY) h-fmax-compare-i-p f-nil) |
|||
|
|||
;****************************************************************************** |
|||
; Instructions |
|||
;------------------------------------------------------------------------------ |
|||
; Binary Arithmetic |
|||
(define-pmacro (fmax-binary-arith op opc sem) |
|||
(dni op |
|||
(.str op " FRd,FRn,FRm") |
|||
(all-fmax-isas MAY_TRAP) |
|||
(.str op " ${fmax-FRd},${fmax-FRn},${fmax-FRm}") |
|||
(+ (f-fmax-0-4 #xF) fmax-FRd (f-fmax-8-4 opc) (f-fmax-12-4 #x7) (f-fmax-16-4 0) |
|||
fmax-FRn fmax-FRm (f-fmax-31-1 0)) |
|||
sem |
|||
() |
|||
) |
|||
) |
|||
|
|||
(fmax-binary-arith fadds #x0 (set fmax-FRd (add fmax-FRn fmax-FRm))) |
|||
(fmax-binary-arith fsubs #x1 (set fmax-FRd (sub fmax-FRn fmax-FRm))) |
|||
(fmax-binary-arith fmuls #x2 (set fmax-FRd (mul fmax-FRn fmax-FRm))) |
|||
(fmax-binary-arith fdivs #x3 (set fmax-FRd (div fmax-FRn fmax-FRm))) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Unary Arithmetic |
|||
(define-pmacro (fmax-unary-arith op opc sem) |
|||
(dni op |
|||
(.str op " FRd,FRn") |
|||
(all-fmax-isas MAY_TRAP) |
|||
(.str op " ${fmax-FRd},${fmax-FRn}") |
|||
(+ (f-fmax-0-4 #xF) fmax-FRd (f-fmax-8-4 opc) (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 0) fmax-FRn (f-fmax-24-4 0) (f-fmax-30-1 0) (f-fmax-31-1 0)) |
|||
sem |
|||
() |
|||
) |
|||
) |
|||
|
|||
(fmax-unary-arith fsqrts #x4 (set fmax-FRd (sqrt fmax-FRn))) |
|||
(fmax-unary-arith fabss #x5 (set fmax-FRd (abs fmax-FRn))) |
|||
(fmax-unary-arith fnegs #x7 (set fmax-FRd (neg fmax-FRn))) |
|||
(fmax-unary-arith fmovs #x6 (set fmax-FRd fmax-FRn)) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Conversions |
|||
(define-pmacro (fmax-conv op opc1 opc2 opnd1 opnd2 sem) |
|||
(dni op |
|||
(.str op " FRd,FRn") |
|||
(all-fmax-isas MAY_TRAP) |
|||
(.str op " ${" opnd1 "},${" opnd2 "}") |
|||
(+ (f-fmax-0-4 #xF) opnd1 (f-fmax-8-4 opc1) (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 opc2) opnd2 (f-fmax-24-4 0) (f-fmax-30-1 0) (f-fmax-31-1 0)) |
|||
sem |
|||
() |
|||
) |
|||
) |
|||
|
|||
(fmax-conv froundws #xC #x0 fmax-FRd-int fmax-FRn (set fmax-FRd-int (c-call SI "fmax_froundws" fmax-FRn))) |
|||
(fmax-conv ftruncws #xD #x0 fmax-FRd-int fmax-FRn (set fmax-FRd-int (c-call SI "fmax_ftruncws" fmax-FRn))) |
|||
(fmax-conv fceilws #xE #x0 fmax-FRd-int fmax-FRn (set fmax-FRd-int (c-call SI "fmax_fceilws" fmax-FRn))) |
|||
(fmax-conv ffloorws #xF #x0 fmax-FRd-int fmax-FRn (set fmax-FRd-int (c-call SI "fmax_ffloorws" fmax-FRn))) |
|||
(fmax-conv fcvtws #x4 #x1 fmax-FRd-int fmax-FRn (set fmax-FRd-int (c-call SI "fmax_fcvtws" fmax-FRn))) |
|||
(fmax-conv fcvtsw #x0 #x9 fmax-FRd fmax-FRn-int (set fmax-FRd (float SF FPCONV-DEFAULT fmax-FRn-int))) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Comparisons |
|||
; |
|||
; Comparison with no exceptions |
|||
(define-pmacro (fmax-f-sem x y) (andif (gt x y) (lt x y))) ; do this to get exception detection |
|||
(define-pmacro (fmax-u-sem x y) (not (orif (lt x y) (orif (eq x y) (gt x y))))) |
|||
(define-pmacro (fmax-e-sem x y) (eq x y)) |
|||
(define-pmacro (fmax-ue-sem x y) (not (orif (lt x y) (gt x y)))) |
|||
(define-pmacro (fmax-l-sem x y) (lt x y)) |
|||
(define-pmacro (fmax-ul-sem x y) (not (orif (gt x y) (eq x y)))) |
|||
(define-pmacro (fmax-le-sem x y) (orif (lt x y) (eq x y))) |
|||
(define-pmacro (fmax-ule-sem x y) (not (gt x y))) |
|||
|
|||
(define-pmacro (fmax-comp cond suffix exceptions) |
|||
(dni (.sym fcmp cond suffix s) |
|||
(.str "fcmp" cond suffix "s FRn,FRm") |
|||
;; Even though the instruction doesn't really trap if EXCEPTIONS |
|||
;; is zero, we don't want gcc to put it in a repeat or erepeat |
|||
;; block because of the hazards between fcmp instructions and |
|||
;; anything that reads CBCR. |
|||
(all-fmax-isas MAY_TRAP) |
|||
(.str "fcmp" cond suffix "s ${fmax-FRn},${fmax-FRm}") |
|||
(+ (f-fmax-0-4 #xF) (f-fmax-4-4 0) (.sym FMAX_ cond suffix) (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 #x2) (f-fmax-28-1 0) fmax-FRn fmax-FRm (f-fmax-31-1 0)) |
|||
(sequence () |
|||
(set fmax-Compare-i-p exceptions) |
|||
(set fmax-CBCR ((.sym fmax- cond -sem) fmax-FRn fmax-FRm)) |
|||
(set fmax-Compare-i-p 0) |
|||
) |
|||
() |
|||
) |
|||
) |
|||
|
|||
; Comparison with no exceptions |
|||
(fmax-comp f "" 0) |
|||
(fmax-comp u "" 0) |
|||
(fmax-comp e "" 0) |
|||
(fmax-comp ue "" 0) |
|||
(fmax-comp l "" 0) |
|||
(fmax-comp ul "" 0) |
|||
(fmax-comp le "" 0) |
|||
(fmax-comp ule "" 0) |
|||
|
|||
; Comparison with exceptions |
|||
(fmax-comp f i 1) |
|||
(fmax-comp u i 1) |
|||
(fmax-comp e i 1) |
|||
(fmax-comp ue i 1) |
|||
(fmax-comp l i 1) |
|||
(fmax-comp ul i 1) |
|||
(fmax-comp le i 1) |
|||
(fmax-comp ule i 1) |
|||
|
|||
;------------------------------------------------------------------------------ |
|||
; Move to/from core registers |
|||
(dni cmov-frn-rm |
|||
"cmov FRn,Rm" |
|||
(all-fmax-isas (INTRINSIC "cmov1")) |
|||
"cmov ${fmax-FRd-int},${fmax-Rm}" |
|||
(+ (f-fmax-0-4 #xF) fmax-FRd-int fmax-Rm (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 #xF) (f-fmax-20-4 0) (f-fmax-24-4 0) |
|||
(f-fmax-29-1 0) (f-fmax-30-1 0) (f-fmax-31-1 0)) |
|||
(set fmax-FRd-int fmax-Rm) |
|||
() |
|||
) |
|||
(dni cmov-rm-frn |
|||
"cmov Rm,FRn" |
|||
(all-fmax-isas (INTRINSIC "cmov2")) |
|||
"cmov ${fmax-Rm},${fmax-FRd-int}" |
|||
(+ (f-fmax-0-4 #xF) fmax-FRd-int fmax-Rm (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 #xF) (f-fmax-20-4 0) (f-fmax-24-4 0) |
|||
(f-fmax-29-1 0) (f-fmax-30-1 0) (f-fmax-31-1 1)) |
|||
(set fmax-Rm fmax-FRd-int) |
|||
() |
|||
) |
|||
(dni cmovc-ccrn-rm |
|||
"cmovc CCRn,Rm" |
|||
(all-fmax-isas (INTRINSIC "cmovc1")) |
|||
"cmovc ${fmax-CCRn},${fmax-Rm}" |
|||
(+ (f-fmax-0-4 #xF) fmax-CCRn fmax-Rm (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 #xF) (f-fmax-20-4 0) (f-fmax-24-4 0) |
|||
(f-fmax-28-1 0) (f-fmax-29-1 0) (f-fmax-30-1 1) (f-fmax-31-1 0)) |
|||
(set fmax-CCRn fmax-Rm) |
|||
() |
|||
) |
|||
(dni cmovc-rm-ccrn |
|||
"cmovc Rm,CCRn" |
|||
(all-fmax-isas (INTRINSIC "cmovc2")) |
|||
"cmovc ${fmax-Rm},${fmax-CCRn}" |
|||
(+ (f-fmax-0-4 #xF) fmax-CCRn fmax-Rm (f-fmax-12-4 #x7) |
|||
(f-fmax-16-4 #xF) (f-fmax-20-4 0) (f-fmax-24-4 0) |
|||
(f-fmax-28-1 0) (f-fmax-29-1 0) (f-fmax-30-1 1) (f-fmax-31-1 1)) |
|||
(set fmax-Rm fmax-CCRn) |
|||
() |
|||
) |
|||
@ -0,0 +1,49 @@ |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
; Insns introduced for the MeP-h1 core |
|||
; |
|||
(dnci stcb_r "store in control bus space" (VOLATILE (MACH h1)) |
|||
"stcb $rn,($rma)" |
|||
(+ MAJ_7 rn rma (f-sub4 12)) |
|||
(c-call VOID "do_stcb" rn (and rma #xffff)) |
|||
((mep (unit u-use-gpr (in usereg rn)) |
|||
(unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec) |
|||
(unit u-stcb)))) |
|||
|
|||
(dnci ldcb_r "load from control bus space" (VOLATILE (MACH h1) (LATENCY 3)) |
|||
"ldcb $rn,($rma)" |
|||
(+ MAJ_7 rn rma (f-sub4 13)) |
|||
(set rn (c-call SI "do_ldcb" (and rma #xffff))) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-ldcb) |
|||
(unit u-exec) |
|||
(unit u-ldcb-gpr (out loadreg rn))))) |
|||
|
|||
(dnci pref "cache prefetch" ((MACH h1) VOLATILE) |
|||
"pref $cimm4,($rma)" |
|||
(+ MAJ_7 cimm4 rma (f-sub4 5)) |
|||
(sequence () |
|||
(c-call VOID "check_option_dcache" pc) |
|||
(c-call VOID "do_cache_prefetch" cimm4 rma pc)) |
|||
((mep (unit u-use-gpr (in usereg rma)) |
|||
(unit u-exec)))) |
|||
File diff suppressed because it is too large
@ -0,0 +1,342 @@ |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
;; This coprocessor definition is being used to verify vliw mode behaviour. |
|||
;; This is a mock-up done by Red Hat and is in no way supposed to represent |
|||
;; a real coprocessor. The hardware is defined in mep-core.cpu. |
|||
|
|||
; Coprocessor registers |
|||
(define-pmacro rh-isa-1 () (ISA ext_cop1_16,ext_cop1_32,ext_cop1_48,ext_cop1_64)) |
|||
|
|||
(define-hardware |
|||
(name h-cr64-rh-1) |
|||
(comment "64-bit coprocessor registers for rh coprocessor for core 1") |
|||
(attrs VIRTUAL rh-isa-1) |
|||
(type register DI (32)) |
|||
(set (index newval) (c-call VOID "h_cr64_set" index newval)) |
|||
(get (index) (c-call DI "h_cr64_get" index)) |
|||
(indices keyword "$c" (.map -reg-pair (.iota 32))) |
|||
) |
|||
|
|||
(define-hardware |
|||
(name h-cr-rh-1) |
|||
(comment "32-bit coprocessor registers for rh coprocessor for core 1") |
|||
(attrs VIRTUAL rh-isa-1) |
|||
(type register SI (32)) |
|||
(set (index newval) (c-call VOID "h_cr64_set" index (ext DI newval))) |
|||
(get (index) (trunc SI (c-call DI "h_cr64_get" index))) |
|||
(indices keyword "$c" (.map -reg-pair (.iota 32))) |
|||
) |
|||
|
|||
(define-hardware |
|||
(name h-ccr-rh-1) |
|||
(comment "Coprocessor control registers for rh coprocessor for core 1") |
|||
(attrs VIRTUAL rh-isa-1) |
|||
(type register SI (64)) |
|||
(set (index newval) (c-call VOID "h_ccr_set" index newval)) |
|||
(get (index) (c-call DI "h_ccr_get" index)) |
|||
(indices keyword "" (.map -ccr-reg-pair (.iota 64))) |
|||
) |
|||
|
|||
; ifields For 16-bit insns |
|||
(dnf f-cphigh4 "High 4 bits" ((ISA ext_cop1_16,ext_cop1_32,ext_cop1_48,ext_cop1_64)) 0 4) |
|||
(dnf f-cpcrn "Copro Reg" ((ISA ext_cop1_16,ext_cop1_32,ext_cop1_48,ext_cop1_64)) 4 5) |
|||
(dnf f-cpcrm "Copro Reg" ((ISA ext_cop1_16,ext_cop1_32,ext_cop1_48,ext_cop1_64)) 11 5) |
|||
(dnf f-uu2 "UU for 16-bit insns" ((ISA ext_cop1_16)) 9 2) |
|||
(dnf f-uu3 "UU for 16-bit insns" ((ISA ext_cop1_16)) 9 3) |
|||
(dnf f-cprm "Core GPR" ((ISA ext_cop1_16)) 12 4) |
|||
|
|||
; ifields For 32-bit insns (some of the above are used too) |
|||
; Notes: |
|||
; |
|||
; f-alone: A value of 0111 means that the insn can run alone in |
|||
; one of the vliw modes. |
|||
; |
|||
; f-seg32: Together f-seg32 and f-seg32-a allow 64 different 32-bit |
|||
; f-seg32-a: insns to be defined. |
|||
(dnf f-seg32 "Enumerate 32 bit-insns" ((ISA ext_cop1_32)) 9 3) |
|||
(dnf f-alone "Run-alone indicator" ((ISA ext_cop1_16,ext_cop1_32,ext_cop1_64)) 12 4) |
|||
(dnf f-seg32-a "Enumerate 32 bit-insns" ((ISA ext_cop1_32)) 21 3) |
|||
(dnf f-code8 "8 bit unsigned immediate" ((ISA ext_cop1_32)) 24 8) |
|||
(dnf f-cpcrm-32 "Corpocessor Reg" ((ISA ext_cop1_32)) 16 5) |
|||
|
|||
; ifields for 48-bit insns |
|||
; Note: Part of f-uu12 can be broken off later to enumerate |
|||
; any 48-bit insns that may be added. |
|||
(dnf f-uu12 "Unusued 12 bits" ((ISA ext_cop1_48)) 4 12) |
|||
(dnf f-code16a "Unsigned immediate" ((ISA ext_cop1_48)) 16 16) |
|||
(dnf f-code16b "Unsigned immediate" ((ISA ext_cop1_48,ext_cop1_64)) 32 16) |
|||
|
|||
; ifields for 64-bit insns |
|||
(dnf f-uu8 "Unsused 8 bits" ((ISA ext_cop1_64)) 4 8) |
|||
(dnf f-uu8a "Unused 13 bits" ((ISA ext_cop1_64)) 16 8) |
|||
(dnf f-seg64 "Enumerate 64-bit insns" ((ISA ext_cop1_64)) 24 8) |
|||
(dnf f-code16c "Unsigned immediate" ((ISA ext_cop1_64)) 48 16) |
|||
(dnf f-cpcrn-64 "Coprocessor Register" ((ISA ext_cop1_64)) 32 5) |
|||
(dnf f-cpcrm-64 "Coprocessor Register" ((ISA ext_cop1_64)) 37 4) |
|||
(dnf f-code23 "23 Bit Unisgned Immediate" ((ISA ext_cop1_64)) 41 23) |
|||
(dnf f-cpccrn-64 "Coprocessor Register" ((ISA ext_cop1_64)) 32 4) |
|||
(dnf f-cpccrm-64 "Core GPR" ((ISA ext_cop1_64)) 36 4) |
|||
(dnf f-code24 "24 Bit Unisgned Immediate" ((ISA ext_cop1_64)) 40 24) |
|||
|
|||
|
|||
; Operands for 16-bit insns |
|||
(dnop cpcrn "cpcrn" ((ISA ext_cop1_16,ext_cop1_32)) h-cr64-rh-1 f-cpcrn) |
|||
(dnop cpcrm "cpcrm" ((ISA ext_cop1_16,ext_cop1_32)) h-cr64-rh-1 f-cpcrm) |
|||
(dnop cprm "cprm" ((ISA ext_cop1_16)) h-gpr f-cprm) |
|||
|
|||
; Additional operands for 32-bit insns |
|||
(dnop code8 "imm8" ((ISA ext_cop1_32)) h-uint f-code8) |
|||
|
|||
; Operands for 48-bit insns |
|||
(dnop code16a "code16a" ((ISA ext_cop1_48)) h-uint f-code16a) |
|||
(dnop code16b "code16b" ((ISA ext_cop1_48,ext_cop1_64)) h-uint f-code16b) |
|||
|
|||
; Additional operands for 64-bit insns |
|||
(dnop code16c "code16c" ((ISA ext_cop1_64)) h-uint f-code16c) |
|||
(dnop cpcrn64 "cpcrn64" ((ISA ext_cop1_64)) h-cr64-rh-1 f-cpcrn-64) |
|||
(dnop cpcrm64 "crm64" ((ISA ext_cop1_64)) h-gpr f-cpcrm-64) |
|||
(dnop cpccrn64 "cpccrn64" ((ISA ext_cop1_64)) h-ccr-rh-1 f-cpccrn-64) |
|||
(dnop cpccrm64 "cpccrm64" ((ISA ext_cop1_64)) h-gpr f-cpccrm-64) |
|||
(dnop cpcode23 "cpcode23" ((ISA ext_cop1_64)) h-uint f-code23) |
|||
(dnop cpcode24 "cpcode24" ((ISA ext_cop1_64)) h-uint f-code24) |
|||
|
|||
|
|||
|
|||
; 16- and 32-bit nops can be defined as normal instructions without |
|||
; any problems. nops take no operands, so nops longer than 32 |
|||
; bits cannot be defined as normal insns since that would result in |
|||
; decodable bits beyond cgen's 32-bit boundary. As a result, we |
|||
; have to use macros and other real insns to create 48- and 64-bit nops. |
|||
; |
|||
; In addition, since the names of the nops that will be created as part |
|||
; of future insn sets are not known at this time, the assembler needs a |
|||
; fixed set of nop names that it can use for automatic nop insertion. |
|||
; The idea is that no matter what those insns are called, we don't want |
|||
; to have to change the C code in the assemblers vliw grouping validation |
|||
; and nop insertion routines. We therefore have to create macros for |
|||
; all nops to map the macro names which are known to the assembler to the |
|||
; names of the real nop insns. |
|||
; |
|||
; These emitted insns in these macros will need to be modified when |
|||
; new nops are defined in new coprocessor insn sets. |
|||
|
|||
; A real 16-bit nop insn exists |
|||
(dnmi cpnop16 "cpnop16" |
|||
((ISA ext_cop1_16)) |
|||
"cpnop16" |
|||
(emit cp16nop) |
|||
) |
|||
|
|||
; A real 32-bit nop insn exists |
|||
(dnmi cpnop32 "cpnop32" |
|||
((ISA ext_cop1_32)) |
|||
"cpnop32" |
|||
(emit cp32nop) |
|||
) |
|||
|
|||
; There is no 48-bit nop insn so we use a real "dummy" insn to enable the nop. |
|||
(dnmi cpnop48 "cpnop48" |
|||
((ISA ext_cop1_48)) |
|||
"cpnop48" |
|||
(emit cpf1nop (code16a 0) (code16b 0)) |
|||
) |
|||
|
|||
; There is no 64-bit nop insn so we use a real "dummy" insn to enable the nop. |
|||
(dnmi cpnop64 "cpnop64" |
|||
((ISA ext_cop1_64)) |
|||
"cpnop64" |
|||
(emit cpf3nop (code16b 0) (code16c 0)) |
|||
) |
|||
|
|||
|
|||
(define-pmacro (dncp116i xname xcomment xattrs xsyntax xformat xsemantics xtiming) (dni-isa xname xcomment xattrs xsyntax xformat xsemantics xtiming ext_cop1_16)) |
|||
(define-pmacro (dncp132i xname xcomment xattrs xsyntax xformat xsemantics xtiming) (dni-isa xname xcomment xattrs xsyntax xformat xsemantics xtiming ext_cop1_32)) |
|||
(define-pmacro (dncp148i xname xcomment xattrs xsyntax xformat xsemantics xtiming) (dni-isa xname xcomment xattrs xsyntax xformat xsemantics xtiming ext_cop1_48)) |
|||
(define-pmacro (dncp164i xname xcomment xattrs xsyntax xformat xsemantics xtiming) (dni-isa xname xcomment xattrs xsyntax xformat xsemantics xtiming ext_cop1_64)) |
|||
|
|||
; 16-Bit Insns |
|||
(dncp116i movcp16 "16-bit coprocessor move insn" |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"movcp16 $cpcrn,$cpcrm" |
|||
(+ (f-cphigh4 1) cpcrn (f-uu2 0) cpcrm) |
|||
(set cpcrn cpcrm) |
|||
() |
|||
) |
|||
|
|||
(dncp116i movcp16a "16-bit coprocessor move insn" |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"movcp16a $cpcrn,$cprm" |
|||
(+ (f-cphigh4 2) cpcrn (f-uu3 0) cprm) |
|||
(set cpcrn (zext DI cprm)) |
|||
() |
|||
) |
|||
|
|||
(dncp116i movcp16b "16-bit coprocessor move insn" |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"movcp16b $cprm,$cpcrn" |
|||
(+ (f-cphigh4 3) cpcrn (f-uu3 0) cprm) |
|||
(set cprm (subword SI cpcrn 1)) |
|||
() |
|||
) |
|||
|
|||
(dncp116i cp16nop "16-bit coprocessor nop" |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"cp16nop" |
|||
(+ (f-cphigh4 0) (f-cpcrn 0) (f-uu2 0) (f-cpcrm 0)) |
|||
(unimp "cp16nop") |
|||
() |
|||
) |
|||
|
|||
; 32-Bit Insns |
|||
(dncp132i cp32nop "32-bit coprocessor nop" |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"cp32nop" |
|||
(+ (f-cphigh4 #xf ) (f-cpcrn 0) (f-seg32 0) (f-alone #x7) |
|||
(f-cpcrm-32 0) (f-seg32-a 0) (f-code8 0)) |
|||
(unimp "cpnop32") |
|||
() |
|||
) |
|||
|
|||
(dncp132i cpf2 "General 32-bit insn for compatibility with toshiba's tests " |
|||
(VLIW64_NO_MATCHING_NOP) |
|||
"cpf2 $code8" |
|||
(+ (f-cphigh4 #xf ) (f-cpcrn 0) (f-seg32 0) (f-alone #x7) |
|||
(f-cpcrm-32 0) (f-seg32-a 1) code8) |
|||
(unimp "cpf2") |
|||
() |
|||
) |
|||
|
|||
; 48-Bit Insns |
|||
(dncp148i cpf1 "48-bit coprocessor helper insn" |
|||
() |
|||
"cpf1 $code16a,$code16b" |
|||
(+ (f-cphigh4 4) (f-uu12 0) code16a code16b) |
|||
(sequence ((HI result)) |
|||
(if (eq code16a 0) |
|||
(set pc (c-call USI "cop_exception" pc)) |
|||
; Set branch condition flags to value of code16a[0:3] |
|||
; Branch condition flags do not exist yet. |
|||
(nop) |
|||
) |
|||
) |
|||
() |
|||
) |
|||
|
|||
(dncp148i cpf1nop "48-bit coprocessor nop insn" |
|||
() |
|||
"cpf1nop $code16a,$code16b" |
|||
(+ (f-cphigh4 5) (f-uu12 0) code16a code16b) |
|||
(sequence ((HI result)) |
|||
(set result (add code16a code16b)) |
|||
) |
|||
() |
|||
) |
|||
|
|||
; 64-Bit Insns |
|||
(dncp164i cpf3 "64-bit coprocessor helper insn" |
|||
() |
|||
"cpf3 $code16b,$code16c" |
|||
(+ (f-cphigh4 #xf) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 0) code16b code16c) |
|||
(sequence ((HI result)) |
|||
(set result (add code16b code16c)) |
|||
) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cpf3nop "64-bit coprocessor helper insn" |
|||
() |
|||
"cpf3nop $code16b,$code16c" |
|||
(+ (f-cphigh4 #xf) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 7) code16b code16c) |
|||
(sequence ((HI result)) |
|||
(set result (add code16b code16c)) |
|||
) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmov64a "64-bit cmov" |
|||
() |
|||
"cmov64a $cpcrn64,$cpcrm64,$cpcode23" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 1) cpcrn64 cpcrm64 cpcode23) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode23) |
|||
(set cpcrn64 (zext DI cpcrm64))) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmov64b "64-bit cmov" |
|||
() |
|||
"cmov64b $cpcrm64,$cpcrn64,$cpcode23" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 2) cpcrn64 cpcrm64 cpcode23) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode23) |
|||
(set cpcrm64 (subword SI cpcrn64 1))) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmovh64a "64-bit cmovh" |
|||
() |
|||
"cmovh64a $cpcrn64,$cpcrm64,$cpcode23" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 3) cpcrn64 cpcrm64 cpcode23) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode23) |
|||
(set cpcrn64 (or (sll (zext DI cpcrm64) 32) (zext DI (subword SI cpcrn64 1))))) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmovh64b "64-bit cmovh" |
|||
() |
|||
"cmovh64b $cpcrm64,$cpcrn64,$cpcode23" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 4) cpcrn64 cpcrm64 cpcode23) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode23) |
|||
(set cpcrm64 (subword SI cpcrn64 0))) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmovc64a "64-bit cmovc" |
|||
() |
|||
"cmovc64a $cpccrn64,$cpccrm64,$cpcode24" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 5) cpccrn64 cpccrm64 cpcode24) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode24) |
|||
(set cpccrn64 cpccrm64)) |
|||
() |
|||
) |
|||
|
|||
(dncp164i cmovc64b "64-bit cmovc" |
|||
() |
|||
"cmovc64b $cpccrm64,$cpccrn64,$cpcode24" |
|||
(+ (f-cphigh4 #xf ) (f-uu8 0) (f-alone 7) (f-uu8a 0) |
|||
(f-seg64 6) cpccrn64 cpccrm64 cpcode24) |
|||
(sequence ((SI dummy)) |
|||
(set dummy cpcode24) |
|||
(set cpccrm64 cpccrn64)) |
|||
() |
|||
) |
|||
|
|||
@ -0,0 +1,120 @@ |
|||
; Toshiba MeP Media Engine architecture description. -*- Scheme -*- |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
|
|||
; This file provides sample definitions for the UCI and DSP |
|||
; instructions. It is incorporated into the overall description by |
|||
; including it from a top-level file that includes all of the required |
|||
; option files. |
|||
|
|||
; UCI option. |
|||
|
|||
(define-pmacro mep-ext1-isa () (ISA ext_core1)) |
|||
|
|||
|
|||
; uci instructions for ELFextension test |
|||
|
|||
; uci.elfext.1 $simm16 |
|||
; 1111_IIII_0000_0010 0001_iiii_iiii_iiii |
|||
; simm16 = I[4:7]||i[20:31] |
|||
|
|||
; uci.elfext.2 $uimm16 |
|||
; 1111_IIII_0000_0010 0010_iiii_iiii_iiii |
|||
; uimm16 = I[4:7]||i[20:31] |
|||
|
|||
; define simm16 |
|||
(df f-uci_elfext_1-hi "uci_elfext_1 simm16 hi 4s7" (mep-ext1-isa) 4 4 INT #f #f) |
|||
(df f-uci_elfext_1-lo "uci_elfext_1 simm16 lo 20s31" (mep-ext1-isa) 20 12 UINT #f #f) |
|||
(define-multi-ifield |
|||
(name f-uci_elfext_1) |
|||
(comment "16-bits uci_elfext_ signed constant") |
|||
(attrs mep-ext1-isa) |
|||
(mode INT) |
|||
(subfields f-uci_elfext_1-hi f-uci_elfext_1-lo) |
|||
(insert (sequence () |
|||
(set (ifield f-uci_elfext_1-hi) (srl (ifield f-uci_elfext_1) 12)) |
|||
(set (ifield f-uci_elfext_1-lo) (and (ifield f-uci_elfext_1) #xfff)))) |
|||
(extract (set (ifield f-uci_elfext_1) |
|||
(or (sll (ifield f-uci_elfext_1-hi) 12) |
|||
(ifield f-uci_elfext_1-lo)))) |
|||
) |
|||
(dpop uci_elfext_1simm16 "signed imm (16 bits)" (mep-ext1-isa) h-sint f-uci_elfext_1 "signed16") |
|||
|
|||
; define uimm16 |
|||
(df f-uci_elfext_2-hi "uci_elfext_2 uimm16 hi 4u7" (mep-ext1-isa) 4 4 UINT #f #f) |
|||
(df f-uci_elfext_2-lo "uci_elfext_2 uimm16 lo 20u31" (mep-ext1-isa) 20 12 UINT #f #f) |
|||
(define-multi-ifield |
|||
(name f-uci_elfext_2) |
|||
(comment "16-bits uci_elfext_ unsigned constant") |
|||
(attrs mep-ext1-isa) |
|||
(mode UINT) |
|||
(subfields f-uci_elfext_2-hi f-uci_elfext_2-lo) |
|||
(insert (sequence () |
|||
(set (ifield f-uci_elfext_2-hi) (srl (ifield f-uci_elfext_2) 12)) |
|||
(set (ifield f-uci_elfext_2-lo) (and (ifield f-uci_elfext_2) #xfff)))) |
|||
(extract (set (ifield f-uci_elfext_2) |
|||
(or (sll (ifield f-uci_elfext_2-hi) 12) |
|||
(ifield f-uci_elfext_2-lo)))) |
|||
) |
|||
(dpop uci_elfext_2uimm16 "unsigned imm (16 bits)" (mep-ext1-isa) h-uint f-uci_elfext_2 "unsigned16") |
|||
|
|||
; define sub-opcode |
|||
(df f-uci_elfext-sub "sub-opcode for uci_elfext instructions" (mep-ext1-isa) 16 4 UINT #f #f) |
|||
|
|||
|
|||
; define instruction |
|||
(dni uci.elfext.1 "uci_elfext instruction 1" (OPTIONAL_UCI_INSN VOLATILE mep-ext1-isa) |
|||
"uci.elfext.1 $uci_elfext_1simm16" |
|||
(+ MAJ_15 (f-rm 0) (f-sub4 2) (f-uci_elfext-sub 1) uci_elfext_1simm16) |
|||
(c-call "check_option_uci" pc) |
|||
() |
|||
) |
|||
|
|||
; define instruction |
|||
(dni uci.elfext.2 "uci_elfext instruction 1" (OPTIONAL_UCI_INSN VOLATILE mep-ext1-isa) |
|||
"uci.elfext.2 $uci_elfext_2uimm16" |
|||
(+ MAJ_15 (f-rm 0) (f-sub4 2) (f-uci_elfext-sub 2) uci_elfext_2uimm16) |
|||
(c-call "check_option_uci" pc) |
|||
() |
|||
) |
|||
|
|||
|
|||
|
|||
;; some general samples |
|||
; UCI option. |
|||
|
|||
(dni uci "user defined instruction" (OPTIONAL_UCI_INSN mep-ext1-isa) |
|||
"uci $rn,$rm,$code16" |
|||
(+ MAJ_15 rn rm (f-sub4 2) code16) |
|||
(sequence () |
|||
(c-call "check_option_uci" pc) |
|||
(unimp "uci")) |
|||
()) |
|||
|
|||
; DSP option. |
|||
|
|||
(dni dsp "dsp instruction" (OPTIONAL_DSP_INSN mep-ext1-isa) |
|||
"dsp $rn,$rm,$code16" |
|||
(+ MAJ_15 rn rm (f-sub4 0) code16) |
|||
(sequence () |
|||
(c-call "check_option_dsp" pc) |
|||
(set pc (c-call USI "dsp_exception" pc))) |
|||
()) |
|||
@ -0,0 +1,21 @@ |
|||
; Copyright 2011 Free Software Foundation, Inc. |
|||
; |
|||
; Contributed by Red Hat Inc; |
|||
; |
|||
; This file is part of the GNU Binutils. |
|||
; |
|||
; This program 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 program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
; MA 02110-1301, USA. |
|||
(include "mep-default.cpu") |
|||
File diff suppressed because it is too large
@ -0,0 +1,774 @@ |
|||
; OpenRISC family. -*- Scheme -*- |
|||
; Copyright 2000, 2001, 2011 Free Software Foundation, Inc. |
|||
; Contributed by Johan Rydberg, jrydberg@opencores.org |
|||
; |
|||
; This program 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 2 of the License, or |
|||
; (at your option) any later version. |
|||
; |
|||
; This program 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 this program; if not, write to the Free Software |
|||
; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
|||
|
|||
(include "simplify.inc") |
|||
|
|||
; OpenRISC 1000 is an architecture of a family of open source, |
|||
; synthesizeable RISC microprocessor cores. It is a 32-bit load |
|||
; and store RISC architecture designed with emphasis on speed, |
|||
; compact instruction set and scalability. OpenRISC 1000 targets |
|||
; wide range of embedded environments. |
|||
|
|||
(define-arch |
|||
(name openrisc) |
|||
(comment "OpenRISC 1000") |
|||
(insn-lsb0? #t) |
|||
(machs openrisc or1300) |
|||
(isas or32) |
|||
) |
|||
|
|||
|
|||
; Attributes |
|||
|
|||
; An attribute to describe if a model has insn and/or data caches. |
|||
(define-attr |
|||
(for model) |
|||
(type enum) |
|||
(name HAS-CACHE) |
|||
(comment "if this model has caches") |
|||
(values DATA-CACHE INSN-CACHE) |
|||
) |
|||
|
|||
; An attribute to describe if an insn can be in the delay slot or not. |
|||
(define-attr |
|||
(for insn) |
|||
(type boolean) |
|||
(name NOT-IN-DELAY-SLOT) |
|||
(comment "insn can't go in delay slot") |
|||
) |
|||
|
|||
; IDOC attribute for instruction documentation. |
|||
|
|||
(define-attr |
|||
(for insn) |
|||
(type enum) |
|||
(name IDOC) |
|||
(comment "insn kind for documentation") |
|||
(attrs META) |
|||
(values |
|||
(MEM - () "Memory") |
|||
(ALU - () "ALU") |
|||
(FPU - () "FPU") |
|||
(BR - () "Branch") |
|||
(PRIV - () "Priviledged") |
|||
(MISC - () "Miscellaneous") |
|||
) |
|||
) |
|||
|
|||
; Enum for exception vectors. |
|||
(define-enum |
|||
(name e-exception) |
|||
(comment "exception vectors") |
|||
(attrs) |
|||
(prefix E_) |
|||
(values (("RESET") ("BUSERR" -) ("DPF" -) ("IPF" -) ("EXTINT" -) ("ALIGN" -) |
|||
("ILLEGAL" -) ("PEINT" -) ("DTLBMISS" -) ("ITLBMISS" -) ("RRANGE" -) |
|||
("SYSCALL" -) ("BREAK" -) ("RESERVED" -))) |
|||
) |
|||
|
|||
|
|||
; Instruction set parameters. |
|||
|
|||
(define-isa |
|||
; Name of the ISA. |
|||
(name or32) |
|||
|
|||
; Base insturction length. The insns is always 32 bits wide. |
|||
(base-insn-bitsize 32) |
|||
|
|||
; Address of insn in delay slot |
|||
(setup-semantics (set-quiet (reg h-delay-insn) (add pc 4))) |
|||
) |
|||
|
|||
|
|||
; CPU family definitions. |
|||
|
|||
(define-cpu |
|||
; CPU names must be distinct from the architecture name and machine names. |
|||
; The "b" suffix stands for "base" and is the convention. |
|||
; The "f" suffix stands for "family" and is the convention. |
|||
(name openriscbf) |
|||
(comment "OpenRISC base family") |
|||
(endian big) |
|||
(word-bitsize 32) |
|||
) |
|||
|
|||
; Generic machine |
|||
(define-mach |
|||
(name openrisc) |
|||
(comment "Generic OpenRISC cpu") |
|||
(cpu openriscbf) |
|||
(bfd-name "openrisc") |
|||
) |
|||
|
|||
; OpenRISC 1300 machine |
|||
(define-mach |
|||
(name or1300) |
|||
(comment "OpenRISC 1300") |
|||
(cpu openriscbf) |
|||
(bfd-name "openrisc:1300") |
|||
) |
|||
|
|||
|
|||
; Model descriptions |
|||
|
|||
; Generic OpenRISC model |
|||
(define-model |
|||
(name openrisc-1) (comment "OpenRISC generic model") (attrs) |
|||
(mach openrisc) |
|||
|
|||
; Nothing special about this. |
|||
(unit u-exec "Execution Unit" () 1 1 () () () ()) |
|||
) |
|||
|
|||
; OpenRISC 1320 |
|||
(define-model |
|||
(name or1320-1) (comment "OpenRISC 1320 model") |
|||
|
|||
; This model has both instruction and data cache |
|||
(attrs (HAS-CACHE INSN-CACHE,DATA-CACHE)) |
|||
(mach or1300) |
|||
|
|||
; Nothing special about this. |
|||
(unit u-exec "Execution Unit" () 1 1 () () () ()) |
|||
) |
|||
|
|||
|
|||
; Instruction fields. |
|||
|
|||
; Attributes: |
|||
; . PCREL-ADDR pc relative value (for reloc and disassembly purposes) |
|||
; . ABS-ADDR absolute address (for reloc and disassembly purposes?) |
|||
; . RESERVED bits are not used to decode insn, must be all 0 |
|||
|
|||
; Instruction classes. |
|||
(dnf f-class "insn class" () 31 2) |
|||
(dnf f-sub "sub class" () 29 4) |
|||
|
|||
; Register fields. |
|||
(dnf f-r1 "r1" () 25 5) |
|||
(dnf f-r2 "r2" () 20 5) |
|||
(dnf f-r3 "r3" () 15 5) |
|||
|
|||
; Immediates. |
|||
(df f-simm16 "signed imm (16)" () 15 16 INT #f #f) |
|||
(dnf f-uimm16 "unsigned imm (16)" () 15 16) |
|||
(dnf f-uimm5 "unsigned imm (5)" () 4 5) |
|||
(df f-hi16 "high 16" () 15 16 INT #f #f) |
|||
(df f-lo16 "low 16" () 15 16 INT #f #f) |
|||
|
|||
; Sub fields |
|||
(dnf f-op1 "op1" () 31 2) |
|||
(dnf f-op2 "op2" () 29 4) |
|||
(dnf f-op3 "op3" () 25 2) |
|||
(dnf f-op4 "op4" () 23 3) |
|||
(dnf f-op5 "op3" () 25 5) |
|||
(dnf f-op6 "op4" () 7 3) |
|||
(dnf f-op7 "op5" () 3 4) |
|||
|
|||
(dnf f-i16-1 "uimm16-1" () 10 11) |
|||
(dnf f-i16-2 "uimm16-2" () 25 5) |
|||
|
|||
; PC relative, 26-bit (2 shifted to right) |
|||
(df f-disp26 "disp26" (PCREL-ADDR) 25 26 INT |
|||
((value pc) (sra WI (sub WI value pc) (const 2))) |
|||
((value pc) (add WI (sll WI value (const 2)) pc))) |
|||
|
|||
; absolute, 26-bit (2 shifted to right) |
|||
(df f-abs26 "abs26" (ABS-ADDR) 25 26 INT |
|||
((value pc) (sra WI pc (const 2))) |
|||
((value pc) (sll WI value (const 2)))) |
|||
|
|||
(define-multi-ifield |
|||
(name f-i16nc) |
|||
(comment "16 bit signed") |
|||
(attrs SIGN-OPT) |
|||
(mode HI) |
|||
(subfields f-i16-1 f-i16-2) |
|||
(insert (sequence () |
|||
(set (ifield f-i16-2) (and (sra (ifield f-i16nc) |
|||
(const 11)) |
|||
(const #x1f))) |
|||
(set (ifield f-i16-1) (and (ifield f-i16nc) |
|||
(const #x7ff))))) |
|||
(extract (sequence () |
|||
(set (ifield f-i16nc) (c-raw-call SI "@arch@_sign_extend_16bit" |
|||
(or (sll (ifield f-i16-2) |
|||
(const 11)) |
|||
(ifield f-i16-1)))))) |
|||
) |
|||
|
|||
|
|||
; Enums. |
|||
|
|||
; insn-class: bits 31-30 |
|||
(define-normal-insn-enum insn-class "FIXME" () OP1_ f-class |
|||
(.map .str (.iota 4)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-sub "FIXME" () OP2_ f-sub |
|||
(.map .str (.iota 16)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-op3 "FIXME" () OP3_ f-op3 |
|||
(.map .str (.iota 4)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-op4 "FIXME" () OP4_ f-op4 |
|||
(.map .str (.iota 8)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-op5 "FIXME" () OP5_ f-op5 |
|||
(.map .str (.iota 32)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-op6 "FIXME" () OP6_ f-op6 |
|||
(.map .str (.iota 8)) |
|||
) |
|||
|
|||
(define-normal-insn-enum insn-op7 "FIXME" () OP7_ f-op7 |
|||
(.map .str (.iota 16)) |
|||
) |
|||
|
|||
|
|||
|
|||
; Hardware pieces. |
|||
; These entries list the elements of the raw hardware. |
|||
; They're also used to provide tables and other elements of the assembly |
|||
; language. |
|||
|
|||
(dnh h-pc "program counter" (PC PROFILE) (pc) () () ()) |
|||
|
|||
(define-hardware |
|||
(name h-gr) (comment "general registers") (attrs PROFILE) |
|||
(type register WI (32)) |
|||
(indices keyword "" |
|||
((r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) (r7 7) |
|||
(r8 8) (r9 9) (r10 10) (r11 11) (r12 12) (r13 13) (r14 14) |
|||
(r15 15) (r16 16) (r17 17) (r18 18) (r19 19) (r20 20) |
|||
(r21 21) (r22 22) (r23 23) (r24 24) (r25 25) (r26 26) |
|||
(r27 27) (r28 28) (r29 29) (r30 30) (r31 31) (lr 11) |
|||
(sp 1) (fp 2))) |
|||
) |
|||
|
|||
(define-hardware |
|||
(name h-sr) (comment "special registers") |
|||
(type register WI (#x20000)) |
|||
(get (index) (c-call SI "@arch@_h_sr_get_handler" index)) |
|||
(set (index newval) (c-call VOID "@arch@_h_sr_set_handler" index newval)) |
|||
) |
|||
|
|||
(dnh h-hi16 "high 16 bits" () (immediate (INT 16)) () () ()) |
|||
(dnh h-lo16 "low 16 bits" () (immediate (INT 16)) () () ()) |
|||
|
|||
(dsh h-cbit "condition bit" () (register BI)) |
|||
(dsh h-delay-insn "delay insn addr" () (register SI)) |
|||
|
|||
|
|||
; Instruction operands. |
|||
|
|||
(dnop sr "special register" (SEM-ONLY) h-sr f-nil) |
|||
(dnop cbit "condition bit" (SEM-ONLY) h-cbit f-nil) |
|||
(dnop simm-16 "16 bit signed immediate" () h-sint f-simm16) |
|||
(dnop uimm-16 "16 bit unsigned immediate" () h-uint f-uimm16) |
|||
(dnop disp-26 "pc-rel 26 bit" () h-iaddr f-disp26) |
|||
(dnop abs-26 "abs 26 bit" () h-iaddr f-abs26) |
|||
(dnop uimm-5 "imm5" () h-uint f-uimm5) |
|||
|
|||
(dnop rD "destination register" () h-gr f-r1) |
|||
(dnop rA "source register A" () h-gr f-r2) |
|||
(dnop rB "source register B" () h-gr f-r3) |
|||
|
|||
(dnop op-f-23 "f-op23" () h-uint f-op4) |
|||
(dnop op-f-3 "f-op3" () h-uint f-op5) |
|||
|
|||
; For hi(foo). |
|||
(define-operand |
|||
(name hi16) (comment "high 16 bit immediate, sign optional") |
|||
(attrs SIGN-OPT) |
|||
(type h-hi16) |
|||
(index f-simm16) |
|||
(handlers (parse "hi16")) |
|||
) |
|||
|
|||
; For lo(foo) |
|||
(define-operand |
|||
(name lo16) (comment "low 16 bit immediate, sign optional") |
|||
(attrs SIGN-OPT) |
|||
(type h-lo16) |
|||
(index f-lo16) |
|||
(handlers (parse "lo16")) |
|||
) |
|||
|
|||
(define-operand |
|||
(name ui16nc) |
|||
(comment "16 bit immediate, sign optional") |
|||
(attrs) |
|||
(type h-lo16) |
|||
(index f-i16nc) |
|||
(handlers (parse "lo16")) |
|||
) |
|||
|
|||
|
|||
; Instructions. |
|||
|
|||
; Branch releated instructions |
|||
|
|||
(dni l-j "jump (absolute iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.j ${abs-26}" |
|||
(+ OP1_0 OP2_0 abs-26) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
(delay 1 (set pc abs-26)) |
|||
() |
|||
) |
|||
|
|||
(dni l-jal "jump and link (absolute iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.jal ${abs-26}" |
|||
(+ OP1_0 OP2_1 abs-26) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
; Set LR to (delay insn addr + 4) |
|||
(sequence () |
|||
(set (reg h-gr 11) (add (reg h-delay-insn) 4)) |
|||
(delay 1 (set pc abs-26))) |
|||
() |
|||
) |
|||
|
|||
(dni l-jr "jump register (absolute iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.jr $rA" |
|||
(+ OP1_0 OP2_5 OP3_0 OP4_0 rA uimm-16) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
(delay 1 (set pc rA)) |
|||
() |
|||
) |
|||
|
|||
(dni l-jalr "jump register and link (absolute iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.jalr $rA" |
|||
(+ OP1_0 OP2_5 OP3_0 OP4_1 rA uimm-16) |
|||
|
|||
; We save the value of rA in a temporary slot before setting |
|||
; the link register. This because "l.jalr r11" would cause |
|||
; a forever-and-ever loop otherwise. |
|||
; |
|||
; We execute the delay slot before doin' the real branch |
|||
(sequence ((WI tmp-slot)) |
|||
(set tmp-slot rA) |
|||
(set (reg h-gr 11) (add (reg h-delay-insn) 4)) |
|||
(delay 1 (set pc tmp-slot))) |
|||
() |
|||
) |
|||
|
|||
(dni l-bal "branch and link (pc relative iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.bal ${disp-26}" |
|||
(+ OP1_0 OP2_2 disp-26) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
; Set LR to (delay insn addr + 4) |
|||
(sequence () |
|||
(set (reg h-gr 11) (add (reg h-delay-insn) 4)) |
|||
(delay 1 (set pc disp-26))) |
|||
() |
|||
) |
|||
|
|||
(dni l-bnf "branch if condition bit not set (pc relative iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.bnf ${disp-26}" |
|||
(+ OP1_0 OP2_3 disp-26) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
(if (eq cbit 0) |
|||
(sequence () |
|||
(delay 1 (set pc disp-26)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-bf "branch if condition bit is set (pc relative iaddr)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.bf ${disp-26}" |
|||
(+ OP1_0 OP2_4 disp-26) |
|||
|
|||
; We execute the delay slot before doin' the real branch |
|||
(if (eq cbit 1) |
|||
(sequence () |
|||
(delay 1 (set pc disp-26)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-brk "break (exception)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.brk ${uimm-16}" |
|||
(+ OP1_0 OP2_5 OP3_3 OP4_0 rA uimm-16) |
|||
|
|||
; FIXME should we do it like this ?? |
|||
(c-call VOID "@cpu@_cpu_brk" uimm-16) |
|||
() |
|||
) |
|||
|
|||
(dni l-rfe "return from exception" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.rfe $rA" |
|||
(+ OP1_0 OP2_5 OP3_0 OP4_2 rA uimm-16) |
|||
(sequence () |
|||
(delay 1 (set pc (c-call SI "@cpu@_cpu_rfe" rA)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-sys "syscall (exception)" |
|||
; This function may not be in delay slot |
|||
(NOT-IN-DELAY-SLOT) |
|||
|
|||
"l.sys ${uimm-16}" |
|||
(+ OP1_0 OP2_5 OP3_2 OP4_0 rA uimm-16) |
|||
(sequence() |
|||
(delay 1 (set pc (c-call SI "@cpu@_except" pc |
|||
#xc00 uimm-16)))) |
|||
() |
|||
) |
|||
|
|||
|
|||
; Misc instructions |
|||
|
|||
(dni l-nop "nop" |
|||
() |
|||
"l.nop" |
|||
(+ OP1_0 OP2_5 OP3_1 OP4_0 rA uimm-16) |
|||
(nop) |
|||
() |
|||
) |
|||
|
|||
(dnmi l-ret "ret" () |
|||
"l.ret" |
|||
(emit l-jr (rA 11) (uimm-16 0)) |
|||
) |
|||
|
|||
(dni l-movhi "movhi" |
|||
(DELAY-SLOT) |
|||
"l.movhi $rD,$hi16" |
|||
(+ OP1_0 OP2_6 hi16 rD rA) |
|||
(set rD (sll WI hi16 (const 16))) |
|||
() |
|||
) |
|||
|
|||
|
|||
; System releated instructions |
|||
|
|||
(dni l-mfsr "mfsr" |
|||
(DELAY-SLOT) |
|||
"l.mfsr $rD,$rA" |
|||
(+ OP1_0 OP2_7 rD rA uimm-16) |
|||
(set rD (c-call SI "@cpu@_cpu_mfsr" rA)) |
|||
() |
|||
) |
|||
|
|||
(dni l-mtsr "mtsr" |
|||
(DELAY-SLOT) |
|||
"l.mtsr $rA,$rB" |
|||
(+ OP1_1 OP2_0 rA rB rD (f-i16-1 0)) |
|||
(c-call VOID "@cpu@_cpu_mtsr" rA rB) |
|||
() |
|||
) |
|||
|
|||
|
|||
|
|||
; Load instructions |
|||
|
|||
(dni l-lw "load word" |
|||
(DELAY-SLOT) |
|||
"l.lw $rD,${simm-16}($rA)" |
|||
(+ OP1_2 OP2_0 rD rA simm-16) |
|||
(set rD (mem SI (add rA simm-16))) |
|||
() |
|||
) |
|||
|
|||
(dni l-lbz "load byte (zero extend)" |
|||
(DELAY-SLOT) |
|||
"l.lbz $rD,${simm-16}($rA)" |
|||
(+ OP1_2 OP2_1 rD rA simm-16) |
|||
(set rD (zext SI (mem QI (add rA simm-16)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-lbs "load byte (sign extend)" |
|||
(DELAY-SLOT) |
|||
"l.lbs $rD,${simm-16}($rA)" |
|||
(+ OP1_2 OP2_2 rD rA simm-16) |
|||
(set rD (ext SI (mem QI (add rA simm-16)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-lhz "load halfword (zero extend)" |
|||
(DELAY-SLOT) |
|||
"l.lhz $rD,${simm-16}($rA)" |
|||
(+ OP1_2 OP2_3 rD simm-16 rA) |
|||
(set rD (zext SI (mem HI (add rA simm-16)))) |
|||
() |
|||
) |
|||
|
|||
(dni l-lhs "load halfword (sign extend)" |
|||
(DELAY-SLOT) |
|||
"l.lhs $rD,${simm-16}($rA)" |
|||
(+ OP1_2 OP2_4 rD rA simm-16) |
|||
(set rD (ext SI (mem HI (add rA simm-16)))) |
|||
() |
|||
) |
|||
|
|||
|
|||
; Store instructions |
|||
; |
|||
; We have to use a multi field since the integer is splited over 2 fields |
|||
|
|||
(define-pmacro (store-insn mnemonic op2-op mode-op) |
|||
(begin |
|||
(dni (.sym l- mnemonic) |
|||
(.str "l." mnemonic " imm(reg)/reg") |
|||
(DELAY-SLOT) |
|||
(.str "l." mnemonic " ${ui16nc}($rA),$rB") |
|||
(+ OP1_3 op2-op rB rD ui16nc) |
|||
(set (mem mode-op (add rA ui16nc)) rB) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
(store-insn sw OP2_5 SI) |
|||
(store-insn sb OP2_6 QI) |
|||
(store-insn sh OP2_7 HI) |
|||
|
|||
|
|||
|
|||
; Shift and rotate instructions |
|||
|
|||
; Reserved fields. |
|||
(dnf f-f-15-8 "nop" (RESERVED) 15 8) |
|||
(dnf f-f-10-3 "nop" (RESERVED) 10 3) |
|||
(dnf f-f-4-1 "nop" (RESERVED) 4 1) |
|||
(dnf f-f-7-3 "nop" (RESERVED) 7 3) |
|||
|
|||
(define-pmacro (shift-insn mnemonic op4-op) |
|||
(begin |
|||
(dni (.sym l- mnemonic) |
|||
(.str "l." mnemonic " reg/reg/reg") |
|||
() |
|||
(.str "l." mnemonic " $rD,$rA,$rB") |
|||
(+ OP1_3 OP2_8 rD rA rB (f-f-10-3 0) op4-op (f-f-4-1 0) OP7_8) |
|||
(set rD (mnemonic rA rB)) |
|||
() |
|||
) |
|||
(dni (.sym l- mnemonic "i") |
|||
(.str "l." mnemonic " reg/reg/imm") |
|||
() |
|||
(.str "l." mnemonic "i $rD,$rA,${uimm-5}") |
|||
(+ OP1_2 OP2_13 rD rA (f-f-15-8 0) op4-op uimm-5) |
|||
(set rD (mnemonic rA uimm-5)) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
(shift-insn sll OP6_0) |
|||
(shift-insn srl OP6_1) |
|||
(shift-insn sra OP6_2) |
|||
(shift-insn ror OP6_4) |
|||
|
|||
|
|||
; Arethmetic insns |
|||
|
|||
; Reserved fields. |
|||
(dnf f-f-10-7 "nop" (RESERVED) 10 7) |
|||
|
|||
(define-pmacro (ar-insn-u mnemonic op2-op op5-op) |
|||
(begin |
|||
(dni (.sym l- mnemonic) |
|||
(.str "l." mnemonic " reg/reg/reg") |
|||
() |
|||
(.str "l." mnemonic " $rD,$rA,$rB") |
|||
(+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) op5-op) |
|||
(set rD (mnemonic rA rB)) |
|||
() |
|||
) |
|||
(dni (.sym l- mnemonic "i") |
|||
(.str "l." mnemonic " reg/reg/lo16") |
|||
() |
|||
(.str "l." mnemonic "i $rD,$rA,$lo16") |
|||
(+ OP1_2 op2-op rD rA lo16) |
|||
(set rD (mnemonic rA (and lo16 #xffff))) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
(define-pmacro (ar-insn-s mnemonic op2-op op5-op) |
|||
(begin |
|||
(dni (.sym l- mnemonic) |
|||
(.str "l." mnemonic " reg/reg/reg") |
|||
() |
|||
(.str "l." mnemonic " $rD,$rA,$rB") |
|||
(+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) op5-op) |
|||
(set rD (mnemonic rA rB)) |
|||
() |
|||
) |
|||
(dni (.sym l- mnemonic "i") |
|||
(.str "l." mnemonic " reg/reg/lo16") |
|||
() |
|||
(.str "l." mnemonic "i $rD,$rA,$lo16") |
|||
(+ OP1_2 op2-op rD rA lo16) |
|||
(set rD (mnemonic rA lo16)) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
(ar-insn-s add OP2_5 OP7_0) |
|||
;;(ar-op-s addc OP2_5 OP7_0) |
|||
(ar-insn-s sub OP2_7 OP7_2) |
|||
(ar-insn-u and OP2_8 OP7_3) |
|||
(ar-insn-u or OP2_9 OP7_4) |
|||
(ar-insn-u xor OP2_10 OP7_5) |
|||
(ar-insn-u mul OP2_11 OP7_6) |
|||
;;(ar-op-u mac OP2_12 OP7_7) |
|||
|
|||
|
|||
(dni l-div "divide (signed)" |
|||
(DELAY-SLOT) |
|||
"l.div $rD,$rA,$rB" |
|||
(+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) OP7_9) |
|||
(if VOID (eq rB (const 0)) |
|||
(c-call VOID "@arch@_cpu_trap" pc (enum SI E_ILLEGAL)) |
|||
(set rD (div rA rB))) |
|||
() |
|||
) |
|||
|
|||
(dni l-divu "divide (unsigned)" |
|||
(DELAY-SLOT) |
|||
"l.divu $rD,$rA,$rB" |
|||
(+ OP1_3 OP2_8 rD rA rB (f-f-10-7 0) OP7_10) |
|||
(if VOID (eq rB (const 0)) |
|||
(c-call VOID "@arch@_cpu_trap" pc (enum SI E_ILLEGAL)) |
|||
(set rD (udiv rA rB))) |
|||
() |
|||
) |
|||
|
|||
|
|||
; Compare instructions |
|||
|
|||
; Reserved fields. |
|||
(dnf f-f-10-11 "nop" (RESERVED) 10 11) |
|||
|
|||
; Register compare (both signed and unsigned) |
|||
(define-pmacro (sf-insn-r op1-op op2-op op3-op op3-op-2 sem-op) |
|||
(begin |
|||
(dni (.sym l- "sf" (.sym sem-op "s")) |
|||
(.str "l." mnemonic " reg/reg") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) "s $rA,$rB") |
|||
(+ op1-op op2-op op3-op-2 rA rB (f-f-10-11 0)) |
|||
(set cbit (sem-op rA rB)) |
|||
() |
|||
) |
|||
(dni (.sym l- "sf" (.sym sem-op "u")) |
|||
(.str "l." mnemonic " reg/reg") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) "u $rA,$rB") |
|||
(+ op1-op op2-op op3-op rA rB (f-f-10-11 0)) |
|||
(set cbit (sem-op rA rB)) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
; Immediate compare (both signed and unsigned) |
|||
(define-pmacro (sf-insn-i op1-op op2-op op3-op op3-op-2 sem-op) |
|||
(begin |
|||
(dni (.sym l- "sf" (.sym sem-op "si")) |
|||
(.str "l." mnemonic "si reg/imm") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) "si $rA,${simm-16}") |
|||
(+ op1-op op2-op op3-op-2 rA simm-16) |
|||
(set cbit (sem-op rA simm-16)) |
|||
() |
|||
) |
|||
(dni (.sym l- "sf" (.sym sem-op "ui")) |
|||
(.str "l." mnemonic "ui reg/imm") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) "ui $rA,${uimm-16}") |
|||
(+ op1-op op2-op op3-op rA uimm-16) |
|||
(set cbit (sem-op rA uimm-16)) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
(define-pmacro (sf-insn op5-op sem-op) |
|||
(begin |
|||
(dni (.sym l- "sf" sem-op) |
|||
(.str "l." mnemonic " reg/reg") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) " $rA,$rB") |
|||
(+ OP1_3 OP2_9 op5-op rA rB (f-f-10-11 0)) |
|||
(set cbit (sem-op rA rB)) |
|||
() |
|||
) |
|||
(dni (.sym l- "sf" (.sym sem-op "i")) |
|||
(.str "l." mnemonic "i reg/imm") |
|||
(DELAY-SLOT) |
|||
(.str "l.sf" (.str sem-op) "i $rA,${simm-16}") |
|||
(+ OP1_2 OP2_14 op5-op rA simm-16) |
|||
(set cbit (sem-op rA simm-16)) |
|||
() |
|||
) |
|||
) |
|||
) |
|||
|
|||
|
|||
(sf-insn-r OP1_3 OP2_9 OP5_2 OP5_6 gt) |
|||
(sf-insn-r OP1_3 OP2_9 OP5_3 OP5_7 ge) |
|||
(sf-insn-r OP1_3 OP2_9 OP5_4 OP5_8 lt) |
|||
(sf-insn-r OP1_3 OP2_9 OP5_5 OP5_9 le) |
|||
|
|||
(sf-insn-i OP1_2 OP2_14 OP5_2 OP5_6 gt) |
|||
(sf-insn-i OP1_2 OP2_14 OP5_3 OP5_7 ge) |
|||
(sf-insn-i OP1_2 OP2_14 OP5_4 OP5_8 lt) |
|||
(sf-insn-i OP1_2 OP2_14 OP5_5 OP5_9 le) |
|||
|
|||
(sf-insn OP5_0 eq) |
|||
(sf-insn OP5_1 ne) |
|||
@ -0,0 +1,164 @@ |
|||
/* OpenRISC opcode support. -*- C -*- |
|||
Copyright 2000, 2001, 2003, 2005, 2011 Free Software Foundation, Inc. |
|||
|
|||
Contributed by Red Hat Inc; |
|||
|
|||
This file is part of the GNU Binutils. |
|||
|
|||
This program 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 program 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 this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
MA 02110-1301, USA. */ |
|||
|
|||
/* This file is an addendum to or32.cpu. Heavy use of C code isn't |
|||
appropriate in .cpu files, so it resides here. This especially applies |
|||
to assembly/disassembly where parsing/printing can be quite involved. |
|||
Such things aren't really part of the specification of the cpu, per se, |
|||
so .cpu files provide the general framework and .opc files handle the |
|||
nitty-gritty details as necessary. |
|||
|
|||
Each section is delimited with start and end markers. |
|||
|
|||
<arch>-opc.h additions use: "-- opc.h" |
|||
<arch>-opc.c additions use: "-- opc.c" |
|||
<arch>-asm.c additions use: "-- asm.c" |
|||
<arch>-dis.c additions use: "-- dis.c" |
|||
<arch>-ibd.h additions use: "-- ibd.h" */ |
|||
|
|||
/* -- opc.h */ |
|||
#undef CGEN_DIS_HASH_SIZE |
|||
#define CGEN_DIS_HASH_SIZE 64 |
|||
#undef CGEN_DIS_HASH |
|||
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) |
|||
|
|||
extern long openrisc_sign_extend_16bit (long); |
|||
/* -- */ |
|||
|
|||
/* -- opc.c */ |
|||
/* -- */ |
|||
|
|||
/* -- asm.c */ |
|||
|
|||
static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); |
|||
|
|||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS |
|||
|
|||
long |
|||
openrisc_sign_extend_16bit (long value) |
|||
{ |
|||
return ((value & 0xffff) ^ 0x8000) - 0x8000; |
|||
} |
|||
|
|||
/* Handle hi(). */ |
|||
|
|||
static const char * |
|||
parse_hi16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result_type; |
|||
unsigned long ret; |
|||
|
|||
if (**strp == '#') |
|||
++*strp; |
|||
|
|||
if (strncasecmp (*strp, "hi(", 3) == 0) |
|||
{ |
|||
bfd_vma value; |
|||
|
|||
*strp += 3; |
|||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, |
|||
& result_type, & value); |
|||
if (**strp != ')') |
|||
return MISSING_CLOSING_PARENTHESIS; |
|||
|
|||
++*strp; |
|||
if (errmsg == NULL |
|||
&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) |
|||
value >>= 16; |
|||
ret = value; |
|||
} |
|||
else |
|||
{ |
|||
if (**strp == '-') |
|||
{ |
|||
long value; |
|||
|
|||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); |
|||
ret = value; |
|||
} |
|||
else |
|||
{ |
|||
unsigned long value; |
|||
|
|||
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); |
|||
ret = value; |
|||
} |
|||
} |
|||
|
|||
*valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; |
|||
return errmsg; |
|||
} |
|||
|
|||
/* Handle lo(). */ |
|||
|
|||
static const char * |
|||
parse_lo16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result_type; |
|||
unsigned long ret; |
|||
|
|||
if (**strp == '#') |
|||
++*strp; |
|||
|
|||
if (strncasecmp (*strp, "lo(", 3) == 0) |
|||
{ |
|||
bfd_vma value; |
|||
|
|||
*strp += 3; |
|||
errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, |
|||
& result_type, & value); |
|||
if (**strp != ')') |
|||
return MISSING_CLOSING_PARENTHESIS; |
|||
|
|||
++*strp; |
|||
ret = value; |
|||
} |
|||
else |
|||
{ |
|||
if (**strp == '-') |
|||
{ |
|||
long value; |
|||
|
|||
errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); |
|||
ret = value; |
|||
} |
|||
else |
|||
{ |
|||
unsigned long value; |
|||
|
|||
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value); |
|||
ret = value; |
|||
} |
|||
} |
|||
|
|||
*valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000; |
|||
return errmsg; |
|||
} |
|||
|
|||
/* -- */ |
|||
|
|||
/* -- ibd.h */ |
|||
extern long openrisc_sign_extend_16bit (long); |
|||
|
|||
/* -- */ |
|||
File diff suppressed because it is too large
@ -0,0 +1,168 @@ |
|||
/* XSTORMY16 opcode support. -*- C -*- |
|||
Copyright 2011 Free Software Foundation, Inc. |
|||
|
|||
Contributed by Red Hat Inc; |
|||
|
|||
This file is part of the GNU Binutils. |
|||
|
|||
This program 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 program 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 this program; if not, write to the Free Software |
|||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
|||
MA 02110-1301, USA. */ |
|||
|
|||
/* This file is an addendum to xstormy16.cpu. Heavy use of C code isn't |
|||
appropriate in .cpu files, so it resides here. This especially applies |
|||
to assembly/disassembly where parsing/printing can be quite involved. |
|||
Such things aren't really part of the specification of the cpu, per se, |
|||
so .cpu files provide the general framework and .opc files handle the |
|||
nitty-gritty details as necessary. |
|||
|
|||
Each section is delimited with start and end markers. |
|||
|
|||
<arch>-opc.h additions use: "-- opc.h" |
|||
<arch>-opc.c additions use: "-- opc.c" |
|||
<arch>-asm.c additions use: "-- asm.c" |
|||
<arch>-dis.c additions use: "-- dis.c" |
|||
<arch>-ibd.h additions use: "-- ibd.h". */ |
|||
|
|||
/* -- opc.h */ |
|||
|
|||
/* Allows reason codes to be output when assembler errors occur. */ |
|||
#define CGEN_VERBOSE_ASSEMBLER_ERRORS |
|||
|
|||
/* We can't use the default hash size because many bits are used by |
|||
operands. */ |
|||
#define CGEN_DIS_HASH_SIZE 1 |
|||
#define CGEN_DIS_HASH(buf, value) 0 |
|||
/* -- */ |
|||
|
|||
/* -- asm.c */ |
|||
|
|||
/* The machine-independent code doesn't know how to disambiguate |
|||
mov (foo),r3 |
|||
and |
|||
mov (r2),r3 |
|||
where 'foo' is a label. This helps it out. */ |
|||
|
|||
static const char * |
|||
parse_mem8 (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
if (**strp == '(') |
|||
{ |
|||
const char *s = *strp; |
|||
|
|||
if (s[1] == '-' && s[2] == '-') |
|||
return _("Bad register in preincrement"); |
|||
|
|||
while (ISALNUM (*++s)) |
|||
; |
|||
if (s[0] == '+' && s[1] == '+' && (s[2] == ')' || s[2] == ',')) |
|||
return _("Bad register in postincrement"); |
|||
if (s[0] == ',' || s[0] == ')') |
|||
return _("Bad register name"); |
|||
} |
|||
else if (cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, |
|||
(long *) valuep) == NULL) |
|||
return _("Label conflicts with register name"); |
|||
else if (strncasecmp (*strp, "rx,", 3) == 0 |
|||
|| strncasecmp (*strp, "rxl,", 3) == 0 |
|||
|| strncasecmp (*strp, "rxh,", 3) == 0) |
|||
return _("Label conflicts with `Rx'"); |
|||
else if (**strp == '#') |
|||
return _("Bad immediate expression"); |
|||
|
|||
return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); |
|||
} |
|||
|
|||
/* For the add and subtract instructions, there are two immediate forms, |
|||
one for small operands and one for large ones. We want to use |
|||
the small one when possible, but we do not want to generate relocs |
|||
of the small size. This is somewhat tricky. */ |
|||
|
|||
static const char * |
|||
parse_small_immediate (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
bfd_vma value; |
|||
enum cgen_parse_operand_result result; |
|||
const char *errmsg; |
|||
|
|||
if (**strp == '@') |
|||
return _("No relocation for small immediate"); |
|||
|
|||
errmsg = (* cd->parse_operand_fn) |
|||
(cd, CGEN_PARSE_OPERAND_INTEGER, strp, opindex, BFD_RELOC_NONE, |
|||
& result, & value); |
|||
|
|||
if (errmsg) |
|||
return errmsg; |
|||
|
|||
if (result != CGEN_PARSE_OPERAND_RESULT_NUMBER) |
|||
return _("Small operand was not an immediate number"); |
|||
|
|||
*valuep = value; |
|||
return NULL; |
|||
} |
|||
|
|||
/* Literal scan be either a normal literal, a @hi() or @lo relocation. */ |
|||
|
|||
static const char * |
|||
parse_immediate16 (CGEN_CPU_DESC cd, |
|||
const char **strp, |
|||
int opindex, |
|||
unsigned long *valuep) |
|||
{ |
|||
const char *errmsg; |
|||
enum cgen_parse_operand_result result; |
|||
bfd_reloc_code_real_type code = BFD_RELOC_NONE; |
|||
bfd_vma value; |
|||
|
|||
if (strncmp (*strp, "@hi(", 4) == 0) |
|||
{ |
|||
*strp += 4; |
|||
code = BFD_RELOC_HI16; |
|||
} |
|||
else |
|||
if (strncmp (*strp, "@lo(", 4) == 0) |
|||
{ |
|||
*strp += 4; |
|||
code = BFD_RELOC_LO16; |
|||
} |
|||
|
|||
if (code == BFD_RELOC_NONE) |
|||
errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); |
|||
else |
|||
{ |
|||
errmsg = cgen_parse_address (cd, strp, opindex, code, &result, &value); |
|||
if ((errmsg == NULL) && |
|||
(result != CGEN_PARSE_OPERAND_RESULT_QUEUED)) |
|||
errmsg = _("Operand is not a symbol"); |
|||
|
|||
*valuep = value; |
|||
if ((code == BFD_RELOC_HI16 || code == BFD_RELOC_LO16) |
|||
&& **strp == ')') |
|||
*strp += 1; |
|||
else |
|||
{ |
|||
errmsg = _("Syntax error: No trailing ')'"); |
|||
return errmsg; |
|||
} |
|||
} |
|||
return errmsg; |
|||
} |
|||
/* -- */ |
|||
Loading…
Reference in new issue