home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / libstuff / hppa.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-21  |  4.1 KB  |  236 lines

  1. #include "stuff/hppa.h"
  2. /*
  3.  * calc_hppa_HILO() is the specific calculation for all left/right type relocs
  4.  * for the hppa relocation for the hp field selectors LR% RR% which allow
  5.  * sharing of the LR% when the round value of the offset is the same.
  6.  * See hppa/reloc.h for more infomation.
  7.  */
  8. __private_extern__
  9. void
  10. calc_hppa_HILO(
  11. unsigned long base,
  12. unsigned long offset,
  13. unsigned long *left21,
  14. unsigned long *right14)
  15. {
  16.     unsigned long rounded;
  17.  
  18.     rounded = (offset + (0x2000/2)) & ~(0x2000 - 1);
  19.  
  20.     *left21   = (base + rounded) & 0xfffff800;
  21.     *right14 = ((base + rounded) & 0x000007ff) + (offset - rounded);
  22. }
  23.  
  24. /* 
  25.  * 2 helper routines for branch displacement calculations on hppa
  26.  */
  27. __private_extern__
  28. unsigned long
  29. assemble_17(
  30. unsigned long x,
  31. unsigned long y,
  32. unsigned long z)
  33. {
  34.     unsigned long temp;
  35.  
  36.     temp = ( ( z &     1 ) << 16 ) |
  37.            ( ( x &  0x1f ) << 11 ) |
  38.            ( ( y &     1 ) << 10 ) |
  39.            ( ( y & 0x7fe ) >> 1);
  40.     if(z)
  41.         temp |= 0xfffe0000;   /* sign extend it */
  42.     return(temp);
  43. }
  44.  
  45. __private_extern__
  46. unsigned long
  47. assemble_21(
  48. unsigned long x)
  49. {
  50.     unsigned long temp;
  51.  
  52.     temp = ( ( x &        1 ) << 20 ) |
  53.            ( ( x &    0xffe ) <<  8 ) |
  54.            ( ( x &   0xc000 ) >>  7 ) |
  55.            ( ( x & 0x1f0000 ) >> 14 ) |
  56.            ( ( x & 0x003000 ) >> 12 );
  57.     return(temp & 0x1fffff);
  58. }
  59.  
  60. /*
  61.  * The following functions are all from hppa_ctrl_funcs.c in the assembler.
  62.  */
  63. __private_extern__
  64. unsigned long
  65. assemble_12(
  66. unsigned long x,
  67. unsigned long y)
  68. {
  69.     unsigned long temp;
  70.  
  71.     temp = ( ( y     & 1 ) << 11 ) |
  72.            ( ( x     & 1 ) << 10 ) |
  73.            ( ( x & 0x7fe ) >> 1);
  74.     return(temp & 0xfff);
  75. }
  76.  
  77. __private_extern__
  78. unsigned long
  79. assemble_3(
  80. unsigned long x)
  81. {
  82.     unsigned long temp;
  83.  
  84.     temp = ( ( x & 1 ) << 2 ) |
  85.            ( ( x & 6 ) >> 1 );
  86.     return(temp & 7);
  87. }
  88.  
  89. __private_extern__
  90. unsigned long
  91. sign_ext(
  92. unsigned long x,
  93. unsigned long len)
  94. {
  95.     unsigned long sign;
  96.     unsigned long result;
  97.     unsigned long len_ones;
  98.     unsigned long i;
  99.  
  100.     i = 0;
  101.     len_ones = 0;
  102.     while(i < len){
  103.         len_ones = (len_ones << 1) | 1;
  104.         i++;
  105.     }
  106.  
  107.     sign = (x >> (len-1)) & 1;
  108.  
  109.     if(sign)
  110.         result = ( ~0 ^ len_ones ) | ( len_ones & x );
  111.     else
  112.         result = len_ones & x;
  113.  
  114.     return(result);
  115. }
  116.  
  117. static
  118. unsigned long 
  119. ones(
  120. unsigned long n)
  121. {
  122.     unsigned long len_ones;
  123.     unsigned long i;
  124.  
  125.     i = 0;
  126.     len_ones = 0;
  127.     while(i < n){
  128.         len_ones = (len_ones << 1) | 1;
  129.         i++;
  130.     }
  131.     return(len_ones);
  132. }
  133.  
  134. __private_extern__
  135. unsigned long
  136. low_sign_ext(
  137. unsigned long x,
  138. unsigned long len)
  139. {
  140.     unsigned long temp1, temp2;
  141.     unsigned long len_ones;
  142.  
  143.     len_ones = ones(len);
  144.  
  145.     temp1 = ( x & 1 ) << (len-1);
  146.     temp2 = ( ( x & 0xfffffffe ) & len_ones ) >> 1;
  147.     return(sign_ext( (temp1 | temp2),len));
  148. }
  149.  
  150. __private_extern__
  151. unsigned long
  152. dis_assemble_21(
  153. unsigned long as21)
  154. {
  155.     unsigned long temp;
  156.  
  157.     temp  = ( as21 & 0x100000 ) >> 20;
  158.     temp |= ( as21 & 0x0ffe00 ) >> 8;
  159.     temp |= ( as21 & 0x000180 ) << 7;
  160.     temp |= ( as21 & 0x00007c ) << 14;
  161.     temp |= ( as21 & 0x000003 ) << 12;
  162.     return(temp);
  163. }
  164.  
  165. __private_extern__
  166. unsigned long
  167. low_sign_unext(
  168. unsigned long x,
  169. unsigned long len)
  170. {
  171.     unsigned long temp;
  172.     unsigned long sign;
  173.     unsigned long rest;
  174.     unsigned long one_bit_at_len;
  175.     unsigned long len_ones;
  176.  
  177.     len_ones = ones(len);
  178.     one_bit_at_len = 1 << (len-1);
  179.  
  180.     temp = sign_unext(x, len);
  181.     sign = temp & one_bit_at_len;
  182.     sign >>= (len - 1);
  183.  
  184.     rest = temp & ( len_ones ^ one_bit_at_len );
  185.     rest <<= 1;
  186.  
  187.     return(rest | sign);
  188. }
  189.  
  190. __private_extern__
  191. void
  192. dis_assemble_17(
  193. unsigned long as17,
  194. unsigned long *x,
  195. unsigned long *y,
  196. unsigned long *z)
  197. {
  198.     *z =   ( as17 & 0x10000 ) >> 16;
  199.     *x =   ( as17 & 0x0f800 ) >> 11;
  200.     *y = ( ( as17 & 0x00400 ) >> 10 ) | ( ( as17 & 0x3ff ) << 1 );
  201. }
  202.  
  203. __private_extern__
  204. unsigned long
  205. sign_unext(
  206. unsigned long x,
  207. unsigned long len)
  208. {
  209.     unsigned long len_ones;
  210.  
  211.     len_ones = ones(len);
  212.     return(x & len_ones);
  213. }
  214.  
  215. __private_extern__
  216. unsigned long
  217. dis_assemble_3(
  218. unsigned long x)
  219. {
  220.     unsigned long r;
  221.  
  222.     r = ( ( (x & 4 ) >> 2 ) | ( ( x & 3 ) << 1 ) ) & 7;
  223.     return(r);
  224. }
  225.  
  226. __private_extern__
  227. void
  228. dis_assemble_12(
  229. unsigned long as12,
  230. unsigned long *x,
  231. unsigned long *y)
  232. {
  233.     *y =   ( as12 & 0x800 ) >> 11;
  234.     *x = ( ( as12 & 0x3ff ) << 1 ) | ( ( as12 & 0x400 ) >> 10 );
  235. }
  236.