int ignore;
{
shl = 1;
+ target_big_endian = 0;
}
const pseudo_typeS md_pseudo_table[] =
sh_opcode_info *opcode;
char *prev_name = "";
+ if (! shl)
+ target_big_endian = 1;
+
opcode_hash_control = hash_new ();
/* Insert unique names into hash table */
static int reg_m;
static int reg_n;
+static int reg_b;
+
static expressionS immediate; /* absolute expression */
typedef struct
int *mode;
int *reg;
{
+ if (src[0] == 'r')
+ {
+ if (src[1] >= '0' && src[1] <= '7' && strncmp(&src[2], "_bank", 5) == 0)
+ {
+ *mode = A_REG_B;
+ *reg = (src[1] - '0');
+ return 7;
+ }
+ }
+
if (src[0] == 'r')
{
if (src[1] == '1')
}
}
+ if (src[0] == 's' && src[1] == 's' && src[2] == 'r')
+ {
+ *mode = A_SSR;
+ return 3;
+ }
+
+ if (src[0] == 's' && src[1] == 'p' && src[2] == 'c')
+ {
+ *mode = A_SPC;
+ return 3;
+ }
+
if (src[0] == 's' && src[1] == 'r')
{
*mode = A_SR;
ptr++;
}
get_operand (&ptr, operand + 1);
+/* start-sanitize-sh3e */
+ if (info->arg[2])
+ {
+ if (*ptr == ',')
+ {
+ ptr++;
+ }
+ get_operand (&ptr, operand + 2);
+ }
+ else
+ {
+ operand[2].type = 0;
+ }
+/* end-sanitize-sh3e */
}
else
{
operand[1].type = 0;
+/* start-sanitize-sh3e */
+ operand[2].type = 0;
+/* end-sanitize-sh3e */
}
}
else
{
operand[0].type = 0;
operand[1].type = 0;
+/* start-sanitize-sh3e */
+ operand[2].type = 0;
+/* end-sanitize-sh3e */
}
return ptr;
}
{
sh_opcode_info *this_try = opcode;
char *name = opcode->name;
- int arg_to_test = 0;
int n = 0;
while (opcode->name)
{
for (n = 0; this_try->arg[n]; n++)
{
- sh_operand_info *user = operands + arg_to_test;
- sh_arg_type arg = this_try->arg[arg_to_test];
+ sh_operand_info *user = operands + n;
+ sh_arg_type arg = this_try->arg[n];
switch (arg)
{
case A_IMM:
if (user->type != A_R0_GBR || user->reg != 0)
goto fail;
break;
+/* start-sanitize-sh3e */
+ case F_FR0:
+ if (user->type != F_REG_N || user->reg != 0)
+ goto fail;
+ break;
+/* end-sanitize-sh3e */
case A_REG_N:
case A_INC_N:
case A_GBR:
case A_SR:
case A_VBR:
+ case A_SSR:
+ case A_SPC:
if (user->type != arg)
goto fail;
break;
+ case A_REG_B:
+ if (user->type != arg)
+ goto fail;
+ reg_b = user->reg;
+ break;
+
case A_REG_M:
case A_INC_M:
case A_DEC_M:
printf ("unhandled %d\n", arg);
goto fail;
}
- /* If we did 0, test 1 next, else 0 */
- arg_to_test = 1 - arg_to_test;
}
return this_try;
fail:;
build_relax (opcode)
sh_opcode_info *opcode;
{
- int high_byte = shl ? 1 : 0 ;
+ int high_byte = target_big_endian ? 0 : 1;
char *p;
if (opcode->arg[0] == A_BDISP8)
int index;
char nbuf[4];
char *output = frag_more (2);
- int low_byte = shl ? 0 : 1;
+ int low_byte = target_big_endian ? 1 : 0;
nbuf[0] = 0;
nbuf[1] = 0;
nbuf[2] = 0;
case REG_M:
nbuf[index] = reg_m;
break;
+ case REG_B:
+ nbuf[index] = reg_b | 0x08;
+ break;
case DISP_4:
insert (output + low_byte, R_SH_IMM4, 0);
break;
}
}
}
- if (shl) {
+ if (! target_big_endian) {
output[1] = (nbuf[0] << 4) | (nbuf[1]);
output[0] = (nbuf[2] << 4) | (nbuf[3]);
}
{
unsigned char *op_start;
unsigned char *op_end;
- sh_operand_info operand[2];
+ sh_operand_info operand[3];
sh_opcode_info *opcode;
char name[20];
int nlen = 0;
*sizeP = prec * 2;
- if (shl)
+ if (! target_big_endian)
{
for (i = prec - 1; i >= 0; i--)
{
break;
case OPTION_LITTLE:
shl = 1;
+ target_big_endian = 0;
break;
default:
{
unsigned char *buffer =
(unsigned char *) (fragP->fr_fix + fragP->fr_literal);
- int highbyte = shl ? 1 : 0;
- int lowbyte = shl ? 0 : 1;
+ int highbyte = target_big_endian ? 0 : 1;
+ int lowbyte = target_big_endian ? 1 : 0;
/* Toggle the true/false bit of the bcond. */
buffer[highbyte] ^= 0x2;
long val;
{
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
- int lowbyte = shl ? 0 : 1;
- int highbyte = shl ? 1 : 0;
+ int lowbyte = target_big_endian ? 1 : 0;
+ int highbyte = target_big_endian ? 0 : 1;
if (fixP->fx_r_type == 0)
{
variable val. */
val = (val + 2) / 4;
if (val & ~0xff)
- as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+ as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
buf[lowbyte] = val;
break;
case R_SH_PCRELIMM8BY2:
val /= 2;
if (val & ~0xff)
- as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+ as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
buf[lowbyte] = val;
break;
case R_SH_PCDISP8BY2:
val /= 2;
if (val < -0x80 || val > 0x7f)
- as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+ as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
buf[lowbyte] = val;
break;
case R_SH_PCDISP:
val /= 2;
if (val < -0x800 || val >= 0x7ff)
- as_warn_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
+ as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far");
buf[lowbyte] = val & 0xff;
buf[highbyte] |= (val >> 8) & 0xf;
break;
case R_SH_IMM32:
- if (shl)
+ if (! target_big_endian)
{
*buf++ = val >> 0;
*buf++ = val >> 8;
break;
case R_SH_IMM16:
- if (shl)
+ if (! target_big_endian)
{
*buf++ = val >> 0;
*buf++ = val >> 8;
valueT use;
int nbytes;
{
- if (shl)
+ if (! target_big_endian)
number_to_chars_littleendian (ptr, use, nbytes);
else
number_to_chars_bigendian (ptr, use, nbytes);