- /* Here to make main operand frag(s). */
- this_add_number = expP->X_add_number;
- this_add_symbol = expP->X_add_symbol;
- to_seg = *segP;
- is_undefined = (to_seg == SEG_UNKNOWN);
- at = operandP->vop_mode & 1;
- length = (operandP->vop_short == 'b'
- ? 1 : (operandP->vop_short == 'w'
- ? 2 : (operandP->vop_short == 'l'
- ? 4 : 0)));
- nbytes = operandP->vop_nbytes;
- if (operandP->vop_access == 'b')
- {
- if (to_seg == now_seg || is_undefined)
- {
- /* If is_undefined, then it might BECOME now_seg. */
- if (nbytes)
- {
- p = frag_more (nbytes);
- fix_new (frag_now, p - frag_now->fr_literal, nbytes,
- this_add_symbol, this_add_number, 1, NO_RELOC);
- }
- else
- { /* to_seg==now_seg || to_seg == SEG_UNKNOWN */
- /* nbytes==0 */
- length_code = is_undefined ? STATE_UNDF : STATE_BYTE;
- if (opcode_as_number & VIT_OPCODE_SPECIAL)
- {
- if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
- {
- /* br or jsb */
- frag_var (rs_machine_dependent, 5, 1,
- ENCODE_RELAX (STATE_ALWAYS_BRANCH, length_code),
- this_add_symbol, this_add_number,
- opcode_low_byteP);
- }
- else
- {
- if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
- {
- length_code = STATE_WORD;
- /* JF: There is no state_byte for this one! */
- frag_var (rs_machine_dependent, 10, 2,
- ENCODE_RELAX (STATE_COMPLEX_BRANCH, length_code),
- this_add_symbol, this_add_number,
- opcode_low_byteP);
- }
- else
- {
- know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
- frag_var (rs_machine_dependent, 9, 1,
- ENCODE_RELAX (STATE_COMPLEX_HOP, length_code),
- this_add_symbol, this_add_number,
- opcode_low_byteP);
- }
- }
- }
- else
- {
- know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
- frag_var (rs_machine_dependent, 7, 1,
- ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, length_code),
- this_add_symbol, this_add_number,
- opcode_low_byteP);
- }
- }
- }
- else
- {
- /* to_seg != now_seg && to_seg != SEG_UNKNOWN */
- /*
- * --- SEG FLOAT MAY APPEAR HERE ----
- */
- if (to_seg == SEG_ABSOLUTE)
- {
- if (nbytes)
- {
- know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
- p = frag_more (nbytes);
- /* Conventional relocation. */
- fix_new (frag_now, p - frag_now->fr_literal,
- nbytes, &abs_symbol, this_add_number,
- 1, NO_RELOC);
- }
- else
- {
- know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
- if (opcode_as_number & VIT_OPCODE_SPECIAL)
- {
- if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
- {
- /* br or jsb */
- *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
- know (opcode_as_chars[1] == 0);
- p = frag_more (5);
- p[0] = VAX_ABSOLUTE_MODE; /* @#... */
- md_number_to_chars (p + 1, this_add_number, 4);
- /* Now (eg) JMP @#foo or JSB @#foo. */
- }
- else
- {
- if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
- {
- p = frag_more (10);
- p[0] = 2;
- p[1] = 0;
- p[2] = VAX_BRB;
- p[3] = 6;
- p[4] = VAX_JMP;
- p[5] = VAX_ABSOLUTE_MODE; /* @#... */
- md_number_to_chars (p + 6, this_add_number, 4);
- /*
- * Now (eg) ACBx 1f
- * BRB 2f
- * 1: JMP @#foo
- * 2:
- */
- }
- else
- {
- know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
- p = frag_more (9);
- p[0] = 2;
- p[1] = VAX_BRB;
- p[2] = 6;
- p[3] = VAX_JMP;
- p[4] = VAX_ABSOLUTE_MODE; /* @#... */
- md_number_to_chars (p + 5, this_add_number, 4);
- /*
- * Now (eg) xOBxxx 1f
- * BRB 2f
- * 1: JMP @#foo
- * 2:
- */
- }
- }
- }
- else
- {
- /* b<cond> */
- *opcode_low_byteP ^= 1;
- /* To reverse the condition in a VAX branch,
- complement the lowest order bit. */
- p = frag_more (7);
- p[0] = 6;
- p[1] = VAX_JMP;
- p[2] = VAX_ABSOLUTE_MODE; /* @#... */
- md_number_to_chars (p + 3, this_add_number, 4);
- /*
- * Now (eg) BLEQ 1f
- * JMP @#foo
- * 1:
- */
- }
- }
- }
- else
- {
- /* to_seg != now_seg && to_seg != SEG_UNKNOWN && to_Seg != SEG_ABSOLUTE */
- if (nbytes > 0)
- {
- /* Pc-relative. Conventional relocation. */
- know (!(opcode_as_number & VIT_OPCODE_SYNTHETIC));
- p = frag_more (nbytes);
- fix_new (frag_now, p - frag_now->fr_literal,
- nbytes, &abs_symbol, this_add_number,
- 1, NO_RELOC);
- }
- else
- {
- know (opcode_as_number & VIT_OPCODE_SYNTHETIC);
- if (opcode_as_number & VIT_OPCODE_SPECIAL)
- {
- if (operandP->vop_width == VAX_WIDTH_UNCONDITIONAL_JUMP)
- {
- /* br or jsb */
- know (opcode_as_chars[1] == 0);
- *opcode_low_byteP = opcode_as_chars[0] + VAX_WIDEN_LONG;
- p = frag_more (5);
- p[0] = VAX_PC_RELATIVE_MODE;
- fix_new (frag_now,
- p + 1 - frag_now->fr_literal, 4,
- this_add_symbol,
- this_add_number, 1, NO_RELOC);
- /* Now eg JMP foo or JSB foo. */
- }
- else
- {
- if (operandP->vop_width == VAX_WIDTH_WORD_JUMP)
- {
- p = frag_more (10);
- p[0] = 0;
- p[1] = 2;
- p[2] = VAX_BRB;
- p[3] = 6;
- p[4] = VAX_JMP;
- p[5] = VAX_PC_RELATIVE_MODE;
- fix_new (frag_now,
- p + 6 - frag_now->fr_literal, 4,
- this_add_symbol,
- this_add_number, 1, NO_RELOC);
- /*
- * Now (eg) ACBx 1f
- * BRB 2f
- * 1: JMP foo
- * 2:
- */
- }
- else
- {
- know (operandP->vop_width == VAX_WIDTH_BYTE_JUMP);
- p = frag_more (10);
- p[0] = 2;
- p[1] = VAX_BRB;
- p[2] = 6;
- p[3] = VAX_JMP;
- p[4] = VAX_PC_RELATIVE_MODE;
- fix_new (frag_now,
- p + 5 - frag_now->fr_literal,
- 4, this_add_symbol,
- this_add_number, 1, NO_RELOC);
- /*
- * Now (eg) xOBxxx 1f
- * BRB 2f
- * 1: JMP foo
- * 2:
- */
- }
- }
- }
- else
- {
- know (operandP->vop_width == VAX_WIDTH_CONDITIONAL_JUMP);
- *opcode_low_byteP ^= 1; /* Reverse branch condition. */
- p = frag_more (7);
- p[0] = 6;
- p[1] = VAX_JMP;
- p[2] = VAX_PC_RELATIVE_MODE;
- fix_new (frag_now, p + 3 - frag_now->fr_literal,
- 4, this_add_symbol,
- this_add_number, 1, NO_RELOC);
- }
- }
- }
- }
- }
- else
- {
- know (operandP->vop_access != 'b'); /* So it is ordinary operand. */
- know (operandP->vop_access != ' '); /* ' ' target-independent: elsewhere. */
- know (operandP->vop_access == 'a'
- || operandP->vop_access == 'm'
- || operandP->vop_access == 'r'
- || operandP->vop_access == 'v'
- || operandP->vop_access == 'w');
- if (operandP->vop_short == 's')
- {
- if (to_seg == SEG_ABSOLUTE)
- {
- if (this_add_number >= 64)
- {
- as_warn (_("Short literal overflow(%ld.), immediate mode assumed."),
- (long) this_add_number);
- operandP->vop_short = 'i';
- operandP->vop_mode = 8;
- operandP->vop_reg = 0xF;
- }
- }
- else
- {
- as_warn (_("Forced short literal to immediate mode. now_seg=%s to_seg=%s"),
- segment_name (now_seg), segment_name (to_seg));
- operandP->vop_short = 'i';
- operandP->vop_mode = 8;
- operandP->vop_reg = 0xF;
- }
- }
- if (operandP->vop_reg >= 0 && (operandP->vop_mode < 8
- || (operandP->vop_reg != 0xF && operandP->vop_mode < 10)))
- {
- /* One byte operand. */
- know (operandP->vop_mode > 3);
- FRAG_APPEND_1_CHAR (operandP->vop_mode << 4 | operandP->vop_reg);
- /* All 1-bytes except S^# happen here. */
- }
- else
- {
- /* {@}{q^}foo{(Rn)} or S^#foo */
- if (operandP->vop_reg == -1 && operandP->vop_short != 's')
- {
- /* "{@}{q^}foo" */
- if (to_seg == now_seg)
- {
- if (length == 0)
- {
- know (operandP->vop_short == ' ');
- p = frag_var (rs_machine_dependent, 10, 2,
- ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE),
- this_add_symbol, this_add_number,
- opcode_low_byteP);
- know (operandP->vop_mode == 10 + at);
- *p = at << 4;
- /* At is the only context we need to carry
- to other side of relax() process. Must
- be in the correct bit position of VAX
- operand spec. byte. */
- }
- else
- {
- know (length);
- know (operandP->vop_short != ' ');
- p = frag_more (length + 1);
- p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
- fix_new (frag_now, p + 1 - frag_now->fr_literal,
- length, this_add_symbol,
- this_add_number, 1, NO_RELOC);
- }
- }
- else
- { /* to_seg != now_seg */
- if (this_add_symbol == NULL)
- {
- know (to_seg == SEG_ABSOLUTE);
- /* Do @#foo: simpler relocation than foo-.(pc) anyway. */
- p = frag_more (5);
- p[0] = VAX_ABSOLUTE_MODE; /* @#... */
- md_number_to_chars (p + 1, this_add_number, 4);
- if (length && length != 4)
- {
- as_warn (_("Length specification ignored. Address mode 9F used"));
- }
- }
- else
- {
- /* {@}{q^}other_seg */
- know ((length == 0 && operandP->vop_short == ' ')
- || (length > 0 && operandP->vop_short != ' '));
- if (is_undefined)
- {
- /*
- * We have a SEG_UNKNOWN symbol. It might
- * turn out to be in the same segment as
- * the instruction, permitting relaxation.
- */
- p = frag_var (rs_machine_dependent, 5, 2,
- ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF),
- this_add_symbol, this_add_number,
- 0);
- p[0] = at << 4;
- }
- else
- {
- if (length == 0)
- {
- know (operandP->vop_short == ' ');
- length = 4; /* Longest possible. */
- }
- p = frag_more (length + 1);
- p[0] = 0xF | ((at + "?\12\14?\16"[length]) << 4);
- md_number_to_chars (p + 1, this_add_number, length);
- fix_new (frag_now,
- p + 1 - frag_now->fr_literal,
- length, this_add_symbol,
- this_add_number, 1, NO_RELOC);
- }
- }
- }
- }
- else
- {
- /* {@}{q^}foo(Rn) or S^# or I^# or # */
- if (operandP->vop_mode < 0xA)
- {
- /* # or S^# or I^# */
- if (operandP->vop_access == 'v'
- || operandP->vop_access == 'a')
- {
- if (operandP->vop_access == 'v')
- as_warn (_("Invalid operand: immediate value used as base address."));
- else
- as_warn (_("Invalid operand: immediate value used as address."));
- /* gcc 2.6.3 is known to generate these in at least
- one case. */
- }
- if (length == 0
- && to_seg == SEG_ABSOLUTE && (expP->X_op != O_big)
- && operandP->vop_mode == 8 /* No '@'. */
- && this_add_number < 64)
- {
- operandP->vop_short = 's';
- }
- if (operandP->vop_short == 's')
- {
- FRAG_APPEND_1_CHAR (this_add_number);
- }
- else
- {
- /* I^#... */
- know (nbytes);
- p = frag_more (nbytes + 1);
- know (operandP->vop_reg == 0xF);
- p[0] = (operandP->vop_mode << 4) | 0xF;
- if ((to_seg == SEG_ABSOLUTE) && (expP->X_op != O_big))
- {
- /*
- * If nbytes > 4, then we are scrod. We
- * don't know if the high order bytes
- * are to be 0xFF or 0x00. BSD4.2 & RMS
- * say use 0x00. OK --- but this
- * assembler needs ANOTHER rewrite to
- * cope properly with this bug. */
- md_number_to_chars (p + 1, this_add_number, min (4, nbytes));
- if (nbytes > 4)
- {
- memset (p + 5, '\0', nbytes - 4);
- }
- }
- else
- {
- if (expP->X_op == O_big)
- {
- /*
- * Problem here is to get the bytes
- * in the right order. We stored
- * our constant as LITTLENUMs, not
- * bytes. */
- LITTLENUM_TYPE *lP;
-
- lP = floatP->low;
- if (nbytes & 1)
- {
- know (nbytes == 1);
- p[1] = *lP;
- }
- else
- {
- for (p++; nbytes; nbytes -= 2, p += 2, lP++)
- {
- md_number_to_chars (p, *lP, 2);
- }
- }
- }
- else
- {
- fix_new (frag_now, p + 1 - frag_now->fr_literal,
- nbytes, this_add_symbol,
- this_add_number, 0, NO_RELOC);
- }
- }
- }
- }
- else
- { /* {@}{q^}foo(Rn) */
- know ((length == 0 && operandP->vop_short == ' ')
- || (length > 0 && operandP->vop_short != ' '));
- if (length == 0)
- {
- if (to_seg == SEG_ABSOLUTE)
- {
- long test;
-
- test = this_add_number;
-
- if (test < 0)
- test = ~test;
-
- length = test & 0xffff8000 ? 4
- : test & 0xffffff80 ? 2
- : 1;
- }
- else
- {
- length = 4;
- }
- }
- p = frag_more (1 + length);
- know (operandP->vop_reg >= 0);
- p[0] = operandP->vop_reg
- | ((at | "?\12\14?\16"[length]) << 4);
- if (to_seg == SEG_ABSOLUTE)
- {
- md_number_to_chars (p + 1, this_add_number, length);
- }
- else
- {
- fix_new (frag_now, p + 1 - frag_now->fr_literal,
- length, this_add_symbol,
- this_add_number, 0, NO_RELOC);
- }
- }
- }
- } /* if(single-byte-operand) */
- }
- } /* for(operandP) */
-} /* vax_assemble() */
-\f
-/*
- * md_estimate_size_before_relax()
- *
- * Called just before relax().
- * Any symbol that is now undefined will not become defined.
- * Return the correct fr_subtype in the frag.
- * Return the initial "guess for fr_var" to caller.
- * The guess for fr_var is ACTUALLY the growth beyond fr_fix.
- * Whatever we do to grow fr_fix or fr_var contributes to our returned value.
- * Although it may not be explicit in the frag, pretend fr_var starts with a
- * 0 value.
- */
-int
-md_estimate_size_before_relax (fragP, segment)
- fragS *fragP;
- segT segment;
-{
- char *p;
- int old_fr_fix;
-
- old_fr_fix = fragP->fr_fix;
- switch (fragP->fr_subtype)
- {
- case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_UNDF):
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- { /* A relaxable case. */
- fragP->fr_subtype = ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE);
- }
- else
- {
- p = fragP->fr_literal + old_fr_fix;
- p[0] |= VAX_PC_RELATIVE_MODE; /* Preserve @ bit. */
- fragP->fr_fix += 1 + 4;
- fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
- fragP->fr_offset, 1, NO_RELOC);
- frag_wane (fragP);
- }
- break;
-
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_UNDF):
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE);
- }
- else
- {
- p = fragP->fr_literal + old_fr_fix;
- *fragP->fr_opcode ^= 1; /* Reverse sense of branch. */
- p[0] = 6;
- p[1] = VAX_JMP;
- p[2] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
- fragP->fr_fix += 1 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 3, 4, fragP->fr_symbol,
- fragP->fr_offset, 1, NO_RELOC);
- frag_wane (fragP);
- }
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_UNDF):
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD);
- }
- else
- {
- p = fragP->fr_literal + old_fr_fix;
- p[0] = 2;
- p[1] = 0;
- p[2] = VAX_BRB;
- p[3] = 6;
- p[4] = VAX_JMP;
- p[5] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
- fragP->fr_fix += 2 + 2 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 6, 4, fragP->fr_symbol,
- fragP->fr_offset, 1, NO_RELOC);
- frag_wane (fragP);
- }
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_UNDF):
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE);
- }
- else
- {
- p = fragP->fr_literal + old_fr_fix;
- p[0] = 2;
- p[1] = VAX_BRB;
- p[2] = 6;
- p[3] = VAX_JMP;
- p[4] = VAX_PC_RELATIVE_MODE; /* ...(pc) */
- fragP->fr_fix += 1 + 2 + 1 + 1 + 4;
- fix_new (fragP, old_fr_fix + 5, 4, fragP->fr_symbol,
- fragP->fr_offset, 1, NO_RELOC);
- frag_wane (fragP);
- }
- break;
-
- case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_UNDF):
- if (S_GET_SEGMENT (fragP->fr_symbol) == segment)
- {
- fragP->fr_subtype = ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE);
- }
- else
- {
- p = fragP->fr_literal + old_fr_fix;
- *fragP->fr_opcode += VAX_WIDEN_LONG;
- p[0] = VAX_PC_RELATIVE_MODE; /* ...(PC) */
- fragP->fr_fix += 1 + 4;
- fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol,
- fragP->fr_offset, 1, NO_RELOC);
- frag_wane (fragP);
- }
- break;
-
- default:
- break;
- }
- return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
-} /* md_estimate_size_before_relax() */
-\f
-/*
- * md_convert_frag();
- *
- * Called after relax() is finished.
- * In: Address of frag.
- * fr_type == rs_machine_dependent.
- * fr_subtype is what the address relaxed to.
- *
- * Out: Any fixSs and constants are set up.
- * Caller will turn frag into a ".space 0".
- */
-void
-md_convert_frag (headers, seg, fragP)
- object_headers *headers;
- segT seg;
- fragS *fragP;
-{
- char *addressP; /* -> _var to change. */
- char *opcodeP; /* -> opcode char(s) to change. */
- short int length_code; /* 2=long 1=word 0=byte */
- short int extension = 0; /* Size of relaxed address. */
- /* Added to fr_fix: incl. ALL var chars. */
- symbolS *symbolP;
- long where;
- long address_of_var;
- /* Where, in file space, is _var of *fragP? */
- long target_address = 0;
- /* Where, in file space, does addr point? */
-
- know (fragP->fr_type == rs_machine_dependent);
- length_code = fragP->fr_subtype & 3; /* depends on ENCODE_RELAX() */
- know (length_code >= 0 && length_code < 3);
- where = fragP->fr_fix;
- addressP = fragP->fr_literal + where;
- opcodeP = fragP->fr_opcode;
- symbolP = fragP->fr_symbol;
- know (symbolP);
- target_address = S_GET_VALUE (symbolP) + fragP->fr_offset;
- address_of_var = fragP->fr_address + where;
-
- switch (fragP->fr_subtype)
- {
-
- case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_BYTE):
- know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
- addressP[0] |= 0xAF; /* Byte displacement. */
- addressP[1] = target_address - (address_of_var + 2);
- extension = 2;
- break;
-
- case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_WORD):
- know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
- addressP[0] |= 0xCF; /* Word displacement. */
- md_number_to_chars (addressP + 1, target_address - (address_of_var + 3), 2);
- extension = 3;
- break;
-
- case ENCODE_RELAX (STATE_PC_RELATIVE, STATE_LONG):
- know (*addressP == 0 || *addressP == 0x10); /* '@' bit. */
- addressP[0] |= 0xEF; /* Long word displacement. */
- md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
- extension = 5;
- break;
-
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_BYTE):
- addressP[0] = target_address - (address_of_var + 1);
- extension = 1;
- break;
-
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_WORD):
- opcodeP[0] ^= 1; /* Reverse sense of test. */
- addressP[0] = 3;
- addressP[1] = VAX_BRB + VAX_WIDEN_WORD;
- md_number_to_chars (addressP + 2, target_address - (address_of_var + 4), 2);
- extension = 4;
- break;
-
- case ENCODE_RELAX (STATE_CONDITIONAL_BRANCH, STATE_LONG):
- opcodeP[0] ^= 1; /* Reverse sense of test. */
- addressP[0] = 6;
- addressP[1] = VAX_JMP;
- addressP[2] = VAX_PC_RELATIVE_MODE;
- md_number_to_chars (addressP + 3, target_address - (address_of_var + 7), 4);
- extension = 7;
- break;
-
- case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_BYTE):
- addressP[0] = target_address - (address_of_var + 1);
- extension = 1;
- break;
-
- case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_WORD):
- opcodeP[0] += VAX_WIDEN_WORD; /* brb -> brw, bsbb -> bsbw */
- md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
- extension = 2;
- break;
-
- case ENCODE_RELAX (STATE_ALWAYS_BRANCH, STATE_LONG):
- opcodeP[0] += VAX_WIDEN_LONG; /* brb -> jmp, bsbb -> jsb */
- addressP[0] = VAX_PC_RELATIVE_MODE;
- md_number_to_chars (addressP + 1, target_address - (address_of_var + 5), 4);
- extension = 5;
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_WORD):
- md_number_to_chars (addressP, target_address - (address_of_var + 2), 2);
- extension = 2;
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_BRANCH, STATE_LONG):
- addressP[0] = 2;
- addressP[1] = 0;
- addressP[2] = VAX_BRB;
- addressP[3] = 6;
- addressP[4] = VAX_JMP;
- addressP[5] = VAX_PC_RELATIVE_MODE;
- md_number_to_chars (addressP + 6, target_address - (address_of_var + 10), 4);
- extension = 10;
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_BYTE):
- addressP[0] = target_address - (address_of_var + 1);
- extension = 1;
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_WORD):
- addressP[0] = 2;
- addressP[1] = VAX_BRB;
- addressP[2] = 3;
- addressP[3] = VAX_BRW;
- md_number_to_chars (addressP + 4, target_address - (address_of_var + 6), 2);
- extension = 6;
- break;
-
- case ENCODE_RELAX (STATE_COMPLEX_HOP, STATE_LONG):
- addressP[0] = 2;
- addressP[1] = VAX_BRB;
- addressP[2] = 6;
- addressP[3] = VAX_JMP;
- addressP[4] = VAX_PC_RELATIVE_MODE;
- md_number_to_chars (addressP + 5, target_address - (address_of_var + 9), 4);
- extension = 9;
- break;
-
- default:
- BAD_CASE (fragP->fr_subtype);
- break;
- }
- fragP->fr_fix += extension;
-} /* md_convert_frag() */
-
-/* Translate internal format of relocation info into target format.
-
- On vax: first 4 bytes are normal unsigned long, next three bytes
- are symbolnum, least sig. byte first. Last byte is broken up with
- the upper nibble as nuthin, bit 3 as extern, bits 2 & 1 as length, and
- bit 0 as pcrel. */
-#ifdef comment
-void
-md_ri_to_chars (the_bytes, ri)
- char *the_bytes;
- struct reloc_info_generic ri;
-{
- /* this is easy */
- md_number_to_chars (the_bytes, ri.r_address, sizeof (ri.r_address));
- /* now the fun stuff */
- the_bytes[6] = (ri.r_symbolnum >> 16) & 0x0ff;
- the_bytes[5] = (ri.r_symbolnum >> 8) & 0x0ff;
- the_bytes[4] = ri.r_symbolnum & 0x0ff;
- the_bytes[7] = (((ri.r_extern << 3) & 0x08) | ((ri.r_length << 1) & 0x06) |
- ((ri.r_pcrel << 0) & 0x01)) & 0x0F;
-}
-
-#endif /* comment */
-
-void
-tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
- char *where;
- fixS *fixP;
- relax_addressT segment_address_in_file;
-{
- /*
- * In: length of relocation (or of address) in chars: 1, 2 or 4.
- * Out: GNU LD relocation length code: 0, 1, or 2.
- */
-
- static const unsigned char nbytes_r_length[] = {42, 0, 1, 42, 2};
- long r_symbolnum;
-
- know (fixP->fx_addsy != NULL);
-
- md_number_to_chars (where,
- fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
- 4);
-
- r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
- ? S_GET_TYPE (fixP->fx_addsy)
- : fixP->fx_addsy->sy_number);
-
- where[6] = (r_symbolnum >> 16) & 0x0ff;
- where[5] = (r_symbolnum >> 8) & 0x0ff;
- where[4] = r_symbolnum & 0x0ff;
- where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
- | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
- | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
-}
-
-/*
- * BUGS, GRIPES, APOLOGIA, etc.
- *
- * The opcode table 'votstrs' needs to be sorted on opcode frequency.
- * That is, AFTER we hash it with hash_...(), we want most-used opcodes
- * to come out of the hash table faster.
- *
- * I am sorry to inflict yet another VAX assembler on the world, but
- * RMS says we must do everything from scratch, to prevent pin-heads
- * restricting this software.
- */
-
-/*
- * This is a vaguely modular set of routines in C to parse VAX
- * assembly code using DEC mnemonics. It is NOT un*x specific.
- *
- * The idea here is that the assembler has taken care of all:
- * labels
- * macros
- * listing
- * pseudo-ops
- * line continuation
- * comments
- * condensing any whitespace down to exactly one space
- * and all we have to do is parse 1 line into a vax instruction
- * partially formed. We will accept a line, and deliver:
- * an error message (hopefully empty)
- * a skeleton VAX instruction (tree structure)
- * textual pointers to all the operand expressions
- * a warning message that notes a silly operand (hopefully empty)
- */
-\f
-/*
- * E D I T H I S T O R Y
- *
- * 17may86 Dean Elsner. Bug if line ends immediately after opcode.
- * 30apr86 Dean Elsner. New vip_op() uses arg block so change call.
- * 6jan86 Dean Elsner. Crock vip_begin() to call vip_op_defaults().
- * 2jan86 Dean Elsner. Invent synthetic opcodes.
- * Widen vax_opcodeT to 32 bits. Use a bit for VIT_OPCODE_SYNTHETIC,
- * which means this is not a real opcode, it is like a macro; it will
- * be relax()ed into 1 or more instructions.
- * Use another bit for VIT_OPCODE_SPECIAL if the op-code is not optimised
- * like a regular branch instruction. Option added to vip_begin():
- * exclude synthetic opcodes. Invent synthetic_votstrs[].
- * 31dec85 Dean Elsner. Invent vit_opcode_nbytes.
- * Also make vit_opcode into a char[]. We now have n-byte vax opcodes,
- * so caller's don't have to know the difference between a 1-byte & a
- * 2-byte op-code. Still need vax_opcodeT concept, so we know how
- * big an object must be to hold an op.code.
- * 30dec85 Dean Elsner. Widen typedef vax_opcodeT in "vax-inst.h"
- * because vax opcodes may be 16 bits. Our crufty C compiler was
- * happily initialising 8-bit vot_codes with 16-bit numbers!
- * (Wouldn't the 'phone company like to compress data so easily!)
- * 29dec85 Dean Elsner. New static table vax_operand_width_size[].
- * Invented so we know hw many bytes a "I^#42" needs in its immediate
- * operand. Revised struct vop in "vax-inst.h": explicitly include
- * byte length of each operand, and it's letter-code datum type.
- * 17nov85 Dean Elsner. Name Change.
- * Due to ar(1) truncating names, we learned the hard way that
- * "vax-inst-parse.c" -> "vax-inst-parse." dropping the "o" off
- * the archived object name. SO... we shortened the name of this
- * source file, and changed the makefile.
- */
-
-/* handle of the OPCODE hash table */