⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vax.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	  fragP->fr_fix += 1 + 4;	  fix_new (fragP, old_fr_fix + 1, 4, fragP->fr_symbol, 0,		   fragP->fr_offset, 1);	  frag_wane (fragP);	}      break;    default:      break;    }  return (fragP->fr_var + fragP->fr_fix - old_fr_fix);}				/* md_estimate_size_before_relax() *//* *			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". */voidmd_convert_frag (fragP)     register fragS *fragP;{  register char *addressP;	/* -> _var to change. */  register char *opcodeP;	/* -> opcode char(s) to change. */  register short int length_code;	/* 2=long 1=word 0=byte */  register short int extension;	/* Size of relaxed address. */  /* Added to fr_fix: incl. ALL var chars. */  register symbolS *symbolP;  register long int where;  register long int address_of_var;  /* Where, in file space, is _var of *fragP? */  register long int target_address;  /* 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 = symbolP->sy_value + 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, 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, 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, 4);      extension = 9;      break;    default:      BAD_CASE (fragP->fr_subtype);      break;    }  fragP->fr_fix += extension;}/* the bit-field entries in the relocation_info struct plays hell   with the byte-order problems of cross-assembly.  So as a hack,   I added this mach. dependent ri twiddler.  Ugly, but it gets   you there. -KWK *//* 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. */void md_ri_to_chars (ri_p, ri)     struct relocation_info *ri_p, ri;{  unsigned char the_bytes[8];  /* 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;  /* now put it back where you found it */  bcopy (the_bytes, (char *) ri_p, sizeof (struct relocation_info));} /* JF this used to be a separate file *//* vax_ins_parse.c - a part for a VAX assembler *//* Copyright (C) 1987 Free Software Foundtation, Inc *//* *       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) *//* *		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. *//* #include <stdio.h> JF for one big happy file *//* JF #include "vax-inst.h"		/* define the tree we parse it into */static char *op_hash = NULL;	/* handle of the OPCODE hash table */ /* NULL means any use before vip_begin() */ /* will crash *//* * In:	1 character, from "bdfghloqpw" being the data-type of an operand *	of a vax instruction. * * Out:	the length of an operand of that type, in bytes. *	Special branch operands types "-?!" have length 0. */static const short int vax_operand_width_size[256] ={#define _ 0  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16,	/* ..b.d.fgh...l..o */  _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _,	/* .q.....w........ */  _, _, 1, _, 8, _, 4, 8, 16, _, _, _, 4, _, _, 16,	/* ..b.d.fgh...l..o */  _, 8, _, _, _, _, _, 2, _, _, _, _, _, _, _, _,	/* .q.....w........ */  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _,  _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _};#undef _/* * This perversion encodes all the vax opcodes as a bunch of strings. * RMS says we should build our hash-table at run-time. Hmm. * Please would someone arrange these in decreasing frequency of opcode? * Because of the way hash_...() works, the most frequently used opcode * should be textually first and so on. * * Input for this table was 'vax.opcodes', awk(1)ed by 'vax.opcodes.c.awk' . * So change 'vax.opcodes', then re-generate this table. */#include "vax-opcode.h"/* * This is a table of optional op-codes. All of them represent * 'synthetic' instructions that seem popular. * * Here we make some pseudo op-codes. Every code has a bit set to say * it is synthetic. This lets you catch them if you want to * ban these opcodes. They are mnemonics for "elastic" instructions * that are supposed to assemble into the fewest bytes needed to do a * branch, or to do a conditional branch, or whatever. * * The opcode is in the usual place [low-order n*8 bits]. This means * that if you mask off the bucky bits, the usual rules apply about * how long the opcode is. * * All VAX branch displacements come at the end of the instruction. * For simple branches (1-byte opcode + 1-byte displacement) the last * operand is coded 'b?' where the "data type" '?' is a clue that we * may reverse the sense of the branch (complement lowest order bit) * and branch around a jump. This is by far the most common case. * That is why the VIT_OPCODE_SYNTHETIC bit is set: it says this is * a 0-byte op-code followed by 2 or more bytes of operand address. * * If the op-code has VIT_OPCODE_SPECIAL set, then we have a more unusual * case. * * For JBSB & JBR the treatment is the similar, except (1) we have a 'bw' * option before (2) we can directly JSB/JMP because there is no condition. * These operands have 'b-' as their access/data type. * * That leaves a bunch of random opcodes: JACBx, JxOBxxx. In these * cases, we do the same idea. JACBxxx are all marked with a 'b!' * JAOBxxx & JSOBxxx are marked with a 'b:'. * */#if (VIT_OPCODE_SYNTHETIC != 0x80000000)You have just broken the encoding below, which assumes the sign bit means 'I am an imaginary instruction'.#endif#if (VIT_OPCODE_SPECIAL != 0x40000000) You have just broken the encoding below, which assumes the 0x40 M bit means 'I am not to be "optimised" the way normal branches are'.#endifstatic const struct vot synthetic_votstrs[] ={  {"jbsb",   {"b-", 0xC0000010}},		/* BSD 4.2 */ /* jsb used already */  {"jbr",   {"b-", 0xC0000011}},		/* BSD 4.2 */  {"jr",   {"b-", 0xC0000011}},		/* consistent */  {"jneq",   {"b?", 0x80000012}},  {"jnequ",   {"b?", 0x80000012}},  {"jeql",   {"b?", 0x80000013}},  {"jeqlu",   {"b?", 0x80000013}},  {"jgtr",   {"b?", 0x80000014}},  {"jleq",   {"b?", 0x80000015}}, /* un-used opcodes here */  {"jgeq",   {"b?", 0x80000018}},  {"jlss",   {"b?", 0x80000019}},  {"jgtru",   {"b?", 0x8000001a}},  {"jlequ",   {"b?", 0x8000001b}},  {"jvc",   {"b?", 0x8000001c}},  {"jvs",   {"b?", 0x8000001d}},  {"jgequ",   {"b?", 0x8000001e}},  {"jcc",   {"b?", 0x8000001e}},  {"jlssu",   {"b?", 0x8000001f}},  {"jcs",   {"b?", 0x8000001f}},  {"jacbw",   {"rwrwmwb!", 0xC000003d}},  {"jacbf",   {"rfrfmfb!", 0xC000004f}},  {"jacbd",   {"rdrdmdb!", 0xC000006f}},  {"jacbb",   {"rbrbmbb!", 0xC000009d}},  {"jacbl",   {"rlrlmlb!", 0xC00000f1}},  {"jacbg",   {"rgrgmgb!", 0xC0004ffd}},  {"jacbh",   {"rhrhmhb!", 0xC0006ffd}},  {"jbs",   {"rlvbb?", 0x800000e0}},  {"jbc",   {"rlvbb?", 0x800000e1}},  {"jbss",   {"rlvbb?", 0x800000e2}},  {"jbcs",   {"rlvbb?", 0x800000e3}},  {"jbsc",   {"rlvbb?", 0x800000e4}},  {"jbcc",   {"rlvbb?", 0x800000e5}},  {"jbssi",   {"rlvbb?", 0x800000e6}},  {"jbcci",   {"rlvbb?", 0x800000e7}},  {"jlbs",   {"rlb?", 0x800000e8}},	/* JF changed from rlvbb? */  {"jlbc",   {"rlb?", 0x800000e9}},	/* JF changed from rlvbb? */  {"jaoblss",   {"rlmlb:", 0xC00000f2}},  {"jaobleq",   {"rlmlb:", 0xC00000f3}},  {"jsobgeq",   {"mlb:", 0xC00000f4}},	/* JF was rlmlb: */  {"jsobgtr",   {"mlb:", 0xC00000f5}},	/* JF was rlmlb: *//* CASEx has no branch addresses in our conception of it. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -