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

📄 ns32k.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
   with a size-tag.   binary: msb -> lsb	0xxxxxxx				byte   			10xxxxxx xxxxxxxx			word   			11xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx	double word             This must be taken care of and we do it here! 		   */void md_number_to_disp(buf,val,n)     char	*buf;     long	val;     char       n;{   switch(n) {  case 1:    if (val < -64 || val > 63)      as_warn("Byte displacement out of range.  line number not valid");    val&=0x7f;#ifdef SHOW_NUM		printf("%x ",val & 0xff);#endif    *buf++=val;    break;  case 2:    if (val < -8192 || val > 8191)      as_warn("Word displacement out of range.  line number not valid");    val&=0x3fff;    val|=0x8000;#ifdef SHOW_NUM		printf("%x ",val>>8 & 0xff);#endif    *buf++=(val>>8);#ifdef SHOW_NUM		printf("%x ",val & 0xff);#endif    *buf++=val;    break;  case 4:    if (val < -0x1f000000 || val >= 0x20000000)    /* if (val < -0x20000000 || val >= 0x20000000) */      as_warn("Double word displacement out of range");    val|=0xc0000000;#ifdef SHOW_NUM		printf("%x ",val>>24 & 0xff);#endif    *buf++=(val>>24);#ifdef SHOW_NUM		printf("%x ",val>>16 & 0xff);#endif    *buf++=(val>>16);#ifdef SHOW_NUM		printf("%x ",val>>8 & 0xff);#endif    *buf++=(val>>8);#ifdef SHOW_NUM		printf("%x ",val & 0xff);#endif    *buf++=val;    break;  default:    as_fatal("Internal logic error");  }}void md_number_to_imm(buf,val,n)     char	*buf;     long	val;     char       n;{   switch(n) {  case 1:#ifdef SHOW_NUM    printf("%x ",val & 0xff);#endif    *buf++=val;    break;  case 2:#ifdef SHOW_NUM		printf("%x ",val>>8 & 0xff);#endif    *buf++=(val>>8);#ifdef SHOW_NUM		printf("%x ",val & 0xff);#endif    *buf++=val;    break;  case 4:#ifdef SHOW_NUM		printf("%x ",val>>24 & 0xff);#endif    *buf++=(val>>24);#ifdef SHOW_NUM		printf("%x ",val>>16 & 0xff);#endif    *buf++=(val>>16);#ifdef SHOW_NUM		printf("%x ",val>>8 & 0xff);#endif    *buf++=(val>>8);#ifdef SHOW_NUM		printf("%x ",val & 0xff);#endif    *buf++=val;    break;  default:    as_fatal("Internal logic error");  }}/* 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 *//* OVE: on a ns32k the twiddling continues at an even deeper level   here we have to distinguish between displacements and immediates.   The sequent has a bit for this. It also has a bit for relocobjects that   points at the target for a bsr (BranchSubRoutine) !?!?!?!   Using [] is importable but fast!! still, its rather funny :-)   This md_ri.... is tailored for sequent.   */void md_ri_to_chars(ri_p, ri)     struct relocation_info *ri_p, ri;{	  if (ri.r_bsr) {ri.r_pcrel=0;} /* sequent seems to want this */  md_number_to_chars((char*)ri_p, ri.r_address, sizeof(ri.r_address));  md_number_to_chars((char*)ri_p+4,		     (long)(ri.r_symbolnum       ) |		     (long)(ri.r_pcrel     << 24 ) |		     (long)(ri.r_length	   << 25 ) |		     (long)(ri.r_extern	   << 27 ) |		     (long)(ri.r_bsr	   << 28 ) |		     (long)(ri.r_disp	   << 29 ),		     4);  /* the first and second md_number_to_chars never overlaps (32bit cpu case) */}/* fast bitfiddling support *//* mask used to zero bitfield before oring in the true field */static unsigned long l_mask[]={	0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,				0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,				0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,				0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,				0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,				0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,				0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,				0xf0000000, 0xe0000000, 0xc0000000, 0x80000000,				};static unsigned long r_mask[]={	0x00000000, 0x00000001, 0x00000003, 0x00000007,				0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,				0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,				0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,				0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,				0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,				0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,				0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,				};#define MASK_BITS 31/* Insert bitfield described by field_ptr and val at buf   This routine is written for modification of the first 4 bytes pointed   to by buf, to yield speed.   The ifdef stuff is for selection between a ns32k-dependent routine   and a general version. (My advice: use the general version!) */void md_number_to_field(buf,val,field_ptr)     register char	*buf;     register long	val;     register bit_fixS  *field_ptr;{   register unsigned long object;  register unsigned long mask;/* define ENDIAN on a ns32k machine */#ifdef ENDIAN  register unsigned long *mem_ptr;#else  register char *mem_ptr;#endif  if (field_ptr->fx_bit_min<=val && val<=field_ptr->fx_bit_max) {#ifdef ENDIAN    if (field_ptr->fx_bit_base) { /* override buf */      mem_ptr=(unsigned long*)field_ptr->fx_bit_base;    } else {      mem_ptr=(unsigned long*)buf;    }#else    if (field_ptr->fx_bit_base) { /* override buf */      mem_ptr=(char*)field_ptr->fx_bit_base;    } else {      mem_ptr=buf;    }#endif    mem_ptr+=field_ptr->fx_bit_base_adj;#ifdef ENDIAN  /* we have a nice ns32k machine with lowbyte at low-physical mem */    object = *mem_ptr; /* get some bytes */#else /* OVE Goof! the machine is a m68k or dito */      /* That takes more byte fiddling */    object=0;    object|=mem_ptr[3] & 0xff;    object<<=8;    object|=mem_ptr[2] & 0xff;    object<<=8;    object|=mem_ptr[1] & 0xff;    object<<=8;    object|=mem_ptr[0] & 0xff;#endif    mask=0;    mask|=(r_mask[field_ptr->fx_bit_offset]);    mask|=(l_mask[field_ptr->fx_bit_offset+field_ptr->fx_bit_size]);    object&=mask;    val+=field_ptr->fx_bit_add;    object|=((val<<field_ptr->fx_bit_offset) & (mask ^ 0xffffffff));#ifdef ENDIAN    *mem_ptr=object;#else    mem_ptr[0]=(char)object;    object>>=8;    mem_ptr[1]=(char)object;    object>>=8;    mem_ptr[2]=(char)object;    object>>=8;    mem_ptr[3]=(char)object;#endif  } else {    as_warn("Bit field out of range");  }}/* Convert a relaxed displacement to dito in final output */void  md_convert_frag(fragP)register fragS *fragP;{  long disp;  long ext;  /* Address in gas core of the place to store the displacement.  */  register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;  /* Address in object code of the displacement.  */  register int object_address = fragP -> fr_fix + fragP -> fr_address;  know(fragP->fr_symbol);  /* The displacement of the address, from current location.  */  disp = (fragP->fr_symbol->sy_value + fragP->fr_offset) - object_address;  disp+= fragP->fr_pcrel_adjust;  switch(fragP->fr_subtype) {  case IND(BRANCH,BYTE):    ext=1;    break;  case IND(BRANCH,WORD):    ext=2;    break;  case IND(BRANCH,DOUBLE):    ext=4;    break;  }  if(ext) {    md_number_to_disp(buffer_address,(long)disp,(int)ext);    fragP->fr_fix+=ext;  }}/* This function returns the estimated size a variable object will occupy,   one can say that we tries to guess the size of the objects before we   actually know it */   md_estimate_size_before_relax(fragP,segtype)     register fragS *fragP;{  int	old_fix;  old_fix=fragP->fr_fix;  switch(fragP->fr_subtype) {  case IND(BRANCH,UNDEF):    if((fragP->fr_symbol->sy_type&N_TYPE)==segtype) {      /* the symbol has been assigned a value */      fragP->fr_subtype=IND(BRANCH,BYTE);    } else {      /* we don't relax symbols defined in an other segment         the thing to do is to assume the object will occupy 4 bytes */      fix_new_ns32k(fragP,		    (int)(fragP->fr_fix),		    4,		    fragP->fr_symbol,		    (symbolS *)0,		    fragP->fr_offset,		    1,		    fragP->fr_pcrel_adjust,		    1,		    0,		    fragP->fr_bsr); /*sequent hack */      fragP->fr_fix+=4;      /* fragP->fr_opcode[1]=0xff; */      frag_wane(fragP);      break;    }  case IND(BRANCH,BYTE):    fragP->fr_var+=1;    break;  default:    break;  }  return fragP->fr_var + fragP->fr_fix - old_fix;}int md_short_jump_size = 3;int md_long_jump_size  = 5;voidmd_create_short_jump(ptr,from_addr,to_addr,frag,to_symbol)char	*ptr;long	from_addr,	to_addr;fragS	*frag;symbolS	*to_symbol;{	long offset;	offset = to_addr - from_addr;	md_number_to_chars(ptr, (long)0xEA  ,1);	md_number_to_disp(ptr+1,(long)offset,2);}voidmd_create_long_jump(ptr,from_addr,to_addr,frag,to_symbol)char	*ptr;long	from_addr,	to_addr;fragS	*frag;symbolS	*to_symbol;{	long offset;	offset= to_addr - from_addr;	md_number_to_chars(ptr, (long)0xEA,  2);	md_number_to_disp(ptr+2,(long)offset,4);}/* JF this is a new function to parse machine-dep options */intmd_parse_option(argP,cntP,vecP)char **argP;int *cntP;char ***vecP;{	switch(**argP) {	case 'm':	  (*argP)++;	  if(!strcmp(*argP,"32032")) {	    cpureg = cpureg_032;	    mmureg = mmureg_032;	  } else if(!strcmp(*argP, "32532")) {	    cpureg = cpureg_532;	    mmureg = mmureg_532;	  } else	    as_warn("Unknown -m option ignored");	  while(**argP)	    (*argP)++;	  break;	default:	  return 0;	}	return 1;}/* *			bit_fix_new() * * Create a bit_fixS in obstack 'notes'. * This struct is used to profile the normal fix. If the bit_fixP is a * valid pointer (not NULL) the bit_fix data will be used to format the fix. */bit_fixS *bit_fix_new (size,offset,min,max,add,base_type,base_adj)     char	size;		/* Length of bitfield		*/     char	offset;		/* Bit offset to bitfield	*/     long	base_type;	/* 0 or 1, if 1 it's exploded to opcode ptr */     long	base_adj;     long	min;		/* Signextended min for bitfield */     long	max;		/* Signextended max for bitfield */     long	add;		/* Add mask, used for huffman prefix */{  register bit_fixS *	bit_fixP;  bit_fixP = (bit_fixS *)obstack_alloc(&notes,sizeof(bit_fixS));  bit_fixP -> fx_bit_size	= size;  bit_fixP -> fx_bit_offset	= offset;  bit_fixP -> fx_bit_base	= base_type;  bit_fixP -> fx_bit_base_adj	= base_adj;  bit_fixP -> fx_bit_max	= max;  bit_fixP -> fx_bit_min	= min;  bit_fixP -> fx_bit_add	= add;  return bit_fixP;}voidfix_new_ns32k (frag, where, size, add_symbol, sub_symbol, offset, pcrel,	 pcrel_adjust, im_disp, bit_fixP, bsr)     fragS *	frag;		/* Which frag? */     int	where;		/* Where in that frag? */     short int	size;		/* 1, 2  or 4 usually. */     symbolS *	add_symbol;	/* X_add_symbol. */     symbolS *	sub_symbol;	/* X_subtract_symbol. */     long int	offset;		/* X_add_number. */     int	pcrel;		/* TRUE if PC-relative relocation. */     char	pcrel_adjust;	/* not zero if adjustment of pcrel offset is needed */     char	im_disp;	/* true if the value to write is a displacement */     bit_fixS *bit_fixP;	/* pointer at struct of bit_fix's, ignored if NULL */     char	bsr;		/* sequent-linker-hack: 1 when relocobject is a bsr */     {  register fixS *	fixP;  fixP = (fixS *)obstack_alloc(&notes,sizeof(fixS));  fixP -> fx_frag		= frag;  fixP -> fx_where		= where;  fixP -> fx_size		= size;  fixP -> fx_addsy		= add_symbol;  fixP -> fx_subsy		= sub_symbol;  fixP -> fx_offset		= offset;  fixP -> fx_pcrel		= pcrel;  fixP -> fx_pcrel_adjust	= pcrel_adjust;  fixP -> fx_im_disp		= im_disp;  fixP -> fx_bit_fixP		= bit_fixP;  fixP -> fx_bsr		= bsr;  fixP -> fx_next		= * seg_fix_rootP;  * seg_fix_rootP = fixP;}

⌨️ 快捷键说明

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