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