- crx_ins->arg[number].constant = crx_ins->exp.X_add_number;
- constant_val = crx_ins->exp.X_add_number;
- if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
- && number == 2)
- {
- LONGLONG temp64 = 0;
- char ptr;
- char temp_str[30];
- unsigned int jump_value = 0;
- int BR_MASK = 0, BR_SIZE = 0;
- temp_str[0] = '\0';
- if (signflag)
- {
- temp_str[0] = '-';
- temp_str[1] = '\0';
- }
- strncat (temp_str, str, strlen (str));
- temp64 = strtoll (temp_str, (char **) &ptr,0);
-
- if (temp64 % 2 != 0)
- as_bad (_("Odd Offset in displacement in Instruction `%s'"),
- ins_parse);
-
- /* Determine the branch size. */
- jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
- if (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
- || ((jump_value & 0xFFFFFF00) == 0x0))
- {
- BR_MASK = 0xFF;
- BR_SIZE = 8;
- }
- else
- if (((jump_value & 0xFF000000) == 0xFF000000)
- || ((jump_value & 0xFF000000) == 0x0))
- {
- BR_MASK = 0xFFFFFF;
- BR_SIZE = 24;
- }
- jump_value = jump_value >> 1;
- crx_ins->arg[number].constant = jump_value & BR_MASK;
- crx_ins->arg[number].size = BR_SIZE;
- size_was_set = 1;
- crx_ins->arg[number].signflag = signflag;
- input_line_pointer = save;
- return crx_ins->exp.X_op;
- }
-
- if (IS_INSN_TYPE (BRANCH_INS)
- || IS_INSN_MNEMONIC ("bal")
- || IS_INSN_TYPE (DCR_BRANCH_INS))
- {
- LONGLONG temp64 = 0;
- char ptr;
- char temp_str[30];
- unsigned int jump_value = 0;
- int BR_MASK = 0, BR_SIZE = 0;
-
- temp_str[0] = '\0';
- if (signflag)
- {
- temp_str[0] = '-';
- temp_str[1] = '\0';
- }
- strncat (temp_str, str, strlen (str));
- temp64 = strtoll (temp_str, (char **) &ptr,0);
-
- if (temp64 % 2 != 0)
- as_bad (_("Odd Offset in displacement in Instruction `%s'"),
- ins_parse);
-
- /* Determine the branch size. */
- jump_value = (unsigned int)temp64 & 0xFFFFFFFF;
- if (!IS_INSN_MNEMONIC ("bal") && !IS_INSN_TYPE (DCR_BRANCH_INS)
- && (((jump_value & 0xFFFFFF00) == 0xFFFFFF00)
- || ((jump_value & 0xFFFFFF00) == 0x0)))
- {
- BR_MASK = 0xFF;
- BR_SIZE = 8;
- }
- else if (((jump_value & 0xFFFF0000) == 0xFFFF0000)
- || ((jump_value & 0xFFFF0000) == 0x0))
- {
- BR_MASK = 0xFFFF;
- BR_SIZE = 16;
- }
- else
- {
- BR_MASK = 0xFFFFFFFF;
- BR_SIZE = 32;
- }
- jump_value = jump_value >> 1;
- crx_ins->arg[number].constant = jump_value & BR_MASK;
- crx_ins->arg[number].size = BR_SIZE;
- size_was_set = 1;
- crx_ins->arg[number].signflag = signflag;
- input_line_pointer = save;
- return crx_ins->exp.X_op;
- }
- /* Fix for movd $0xF12344, r0 -- signflag has to be set. */
- if (constant_val < 0 && signflag != 1
- && !IS_INSN_TYPE (LD_STOR_INS) && !IS_INSN_TYPE (LD_STOR_INS_INC)
- && !IS_INSN_TYPE (CSTBIT_INS) && !IS_INSN_TYPE (STOR_IMM_INS)
- && !IS_INSN_TYPE (BRANCH_INS) && !IS_INSN_MNEMONIC ("bal"))
- {
- crx_ins->arg[number].constant =
- ~(crx_ins->arg[number].constant) + 1;
- signflag = 1;
- }
- /* For load/store instruction when the value is in the offset part. */
- if (constant_val < 0 && signflag != 1
- && (IS_INSN_TYPE (LD_STOR_INS) || IS_INSN_TYPE (LD_STOR_INS_INC)
- || IS_INSN_TYPE (CSTBIT_INS) || IS_INSN_TYPE (STOR_IMM_INS)))
- {
- if (crx_ins->arg[number].type == arg_cr
- || crx_ins->arg[number].type == arg_icr)
- {
- crx_ins->arg[number].constant =
- ~(crx_ins->arg[number].constant) + 1;
- signflag = 1;
- }
- }
- if (signflag)
- {
- /* Signflag in never set in case of load store instructions
- Mapping in case of only the arithinsn case. */
- if ((crx_ins->arg[number].constant != 1
- && crx_ins->arg[number].constant != 4)
- || (!IS_INSN_TYPE (ARITH_INS)
- && !IS_INSN_TYPE (ARITH_BYTE_INS)
- && !IS_INSN_TYPE (CMPBR_INS)))
- {
- /* Counting the number of bits required to represent
- the constant. */
- cnt = 0;
- temp = crx_ins->arg[number].constant - 1;
- while (temp > 0)
- {
- temp >>= 1;
- cnt++;
- }
- crx_ins->arg[number].size = cnt + 1;
- crx_ins->arg[number].constant =
- ~(crx_ins->arg[number].constant) + 1;
- if (IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
- {
- char ptr;
- LONGLONG temp64;
-
- temp64 = strtoull (str, (char **) &ptr, 0);
- if (cnt < 4)
- crx_ins->arg[number].size = 5;
-
- if (IS_INSN_TYPE (ARITH_INS))
- {
- if (crx_ins->arg[number].size > 32
- || (temp64 > ULONG_MAX))
- {
- if (crx_ins->arg[number].size > 32)
- as_bad (_("In Instruction `%s': Immediate size is \
- %lu bits cannot be accomodated"),
- ins_parse, cnt + 1);
-
- if (temp64 > ULONG_MAX)
- as_bad (_("Value given more than 32 bits in \
- Instruction `%s'"), ins_parse);
- }
- }
- if (IS_INSN_TYPE (ARITH_BYTE_INS))
- {
- if (crx_ins->arg[number].size > 16
- || !((temp64 & 0xFFFF0000) == 0xFFFF0000
- || (temp64 & 0xFFFF0000) == 0x0))
- {
- if (crx_ins->arg[number].size > 16)
- as_bad (_("In Instruction `%s': Immediate size is \
- %lu bits cannot be accomodated"),
- ins_parse, cnt + 1);
-
- if (!((temp64 & 0xFFFF0000) == 0xFFFF0000
- || (temp64 & 0xFFFF0000) == 0x0))
- as_bad (_("Value given more than 16 bits in \
- Instruction `%s'"), ins_parse);
- }
- }
- }
- if (IS_INSN_TYPE (LD_STOR_INS) && crx_ins->arg[number].type == arg_cr
- && !post_inc_mode)
- {
- /* Cases handled ---
- dispub4/dispuw4/dispud4 and for load store dispubwd4
- is applicable only. */
- if (crx_ins->arg[number].size <= 4)
- crx_ins->arg[number].size = 5;
- }
- /* Argument number is checked to distinguish between
- immediate and displacement in cmpbranch and bcopcond. */
- if ((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
- && number == 2)
- {
- if (crx_ins->arg[number].size != 32)
- crx_ins->arg[number].constant =
- crx_ins->arg[number].constant >> 1;
- }
-
- mask_const (&crx_ins->arg[number].constant,
- (int) crx_ins->arg[number].size);
- }
- }
- else
- {
- /* Argument number is checked to distinguish between
- immediate and displacement in cmpbranch and bcopcond. */
- if (((IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (COP_BRANCH_INS))
- && number == 2)
- || IS_INSN_TYPE (BRANCH_NEQ_INS))
- {
- if (IS_INSN_TYPE (BRANCH_NEQ_INS))
- {
- if (crx_ins->arg[number].constant == 0)
- as_bad (_("Instruction `%s' has Zero offset"), ins_parse);
- }
-
- if (crx_ins->arg[number].constant % 2 != 0)
- as_bad (_("Instruction `%s' has odd offset"), ins_parse);
-
- if (IS_INSN_TYPE (BRANCH_NEQ_INS))
- {
- if (crx_ins->arg[number].constant > 32
- || crx_ins->arg[number].constant < 2)
- as_bad (_("Instruction `%s' has illegal offset (%ld)"),
- ins_parse, crx_ins->arg[number].constant);
-
- crx_ins->arg[number].constant -= 2;
- }
-
- crx_ins->arg[number].constant =
- crx_ins->arg[number].constant >> 1;
- get_number_of_bits (crx_ins, number);
- }
-
- /* Compare branch argument number zero to be compared -
- mapped to cst4. */
- if (IS_INSN_TYPE (CMPBR_INS) && number == 0)
- {
- for (cst4_op = cst4_map; cst4_op < (cst4_map + cst4_maps); cst4_op++)
- {
- if (crx_ins->arg[number].constant == (unsigned int)cst4_op->value)
- {
- crx_ins->arg[number].constant = cst4_op->binary;
- is_cst4 = 1;
- break;
- }
- }
- if (!is_cst4)
- as_bad (_("Instruction `%s' has invalid imm value as an \
- operand"), ins_parse);
- }
- }