1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23#include <stdint.h> 24#include "stuff/hppa.h" 25/* 26 * calc_hppa_HILO() is the specific calculation for all left/right type relocs 27 * for the hppa relocation for the hp field selectors LR% RR% which allow 28 * sharing of the LR% when the round value of the offset is the same. 29 * See hppa/reloc.h for more infomation. 30 */ 31__private_extern__ 32void 33calc_hppa_HILO( 34uint32_t base, 35uint32_t offset, 36uint32_t *left21, 37uint32_t *right14) 38{ 39 uint32_t rounded; 40 41 rounded = (offset + (0x2000/2)) & ~(0x2000 - 1); 42 43 *left21 = (base + rounded) & 0xfffff800; 44 *right14 = ((base + rounded) & 0x000007ff) + (offset - rounded); 45} 46 47/* 48 * 2 helper routines for branch displacement calculations on hppa 49 */ 50__private_extern__ 51uint32_t 52assemble_17( 53uint32_t x, 54uint32_t y, 55uint32_t z) 56{ 57 uint32_t temp; 58 59 temp = ( ( z & 1 ) << 16 ) | 60 ( ( x & 0x1f ) << 11 ) | 61 ( ( y & 1 ) << 10 ) | 62 ( ( y & 0x7fe ) >> 1); 63 if(z) 64 temp |= 0xfffe0000; /* sign extend it */ 65 return(temp); 66} 67 68__private_extern__ 69uint32_t 70assemble_21( 71uint32_t x) 72{ 73 uint32_t temp; 74 75 temp = ( ( x & 1 ) << 20 ) | 76 ( ( x & 0xffe ) << 8 ) | 77 ( ( x & 0xc000 ) >> 7 ) | 78 ( ( x & 0x1f0000 ) >> 14 ) | 79 ( ( x & 0x003000 ) >> 12 ); 80 return(temp & 0x1fffff); 81} 82 83/* 84 * The following functions are all from hppa_ctrl_funcs.c in the assembler. 85 */ 86__private_extern__ 87uint32_t 88assemble_12( 89uint32_t x, 90uint32_t y) 91{ 92 uint32_t temp; 93 94 temp = ( ( y & 1 ) << 11 ) | 95 ( ( x & 1 ) << 10 ) | 96 ( ( x & 0x7fe ) >> 1); 97 return(temp & 0xfff); 98} 99 100__private_extern__ 101uint32_t 102assemble_3( 103uint32_t x) 104{ 105 uint32_t temp; 106 107 temp = ( ( x & 1 ) << 2 ) | 108 ( ( x & 6 ) >> 1 ); 109 return(temp & 7); 110} 111 112__private_extern__ 113uint32_t 114sign_ext( 115uint32_t x, 116uint32_t len) 117{ 118 uint32_t sign; 119 uint32_t result; 120 uint32_t len_ones; 121 uint32_t i; 122 123 i = 0; 124 len_ones = 0; 125 while(i < len){ 126 len_ones = (len_ones << 1) | 1; 127 i++; 128 } 129 130 sign = (x >> (len-1)) & 1; 131 132 if(sign) 133 result = ( ~0 ^ len_ones ) | ( len_ones & x ); 134 else 135 result = len_ones & x; 136 137 return(result); 138} 139 140static 141uint32_t 142ones( 143uint32_t n) 144{ 145 uint32_t len_ones; 146 uint32_t i; 147 148 i = 0; 149 len_ones = 0; 150 while(i < n){ 151 len_ones = (len_ones << 1) | 1; 152 i++; 153 } 154 return(len_ones); 155} 156 157__private_extern__ 158uint32_t 159low_sign_ext( 160uint32_t x, 161uint32_t len) 162{ 163 uint32_t temp1, temp2; 164 uint32_t len_ones; 165 166 len_ones = ones(len); 167 168 temp1 = ( x & 1 ) << (len-1); 169 temp2 = ( ( x & 0xfffffffe ) & len_ones ) >> 1; 170 return(sign_ext( (temp1 | temp2),len)); 171} 172 173__private_extern__ 174uint32_t 175dis_assemble_21( 176uint32_t as21) 177{ 178 uint32_t temp; 179 180 temp = ( as21 & 0x100000 ) >> 20; 181 temp |= ( as21 & 0x0ffe00 ) >> 8; 182 temp |= ( as21 & 0x000180 ) << 7; 183 temp |= ( as21 & 0x00007c ) << 14; 184 temp |= ( as21 & 0x000003 ) << 12; 185 return(temp); 186} 187 188__private_extern__ 189uint32_t 190low_sign_unext( 191uint32_t x, 192uint32_t len) 193{ 194 uint32_t temp; 195 uint32_t sign; 196 uint32_t rest; 197 uint32_t one_bit_at_len; 198 uint32_t len_ones; 199 200 len_ones = ones(len); 201 one_bit_at_len = 1 << (len-1); 202 203 temp = sign_unext(x, len); 204 sign = temp & one_bit_at_len; 205 sign >>= (len - 1); 206 207 rest = temp & ( len_ones ^ one_bit_at_len ); 208 rest <<= 1; 209 210 return(rest | sign); 211} 212 213__private_extern__ 214void 215dis_assemble_17( 216uint32_t as17, 217uint32_t *x, 218uint32_t *y, 219uint32_t *z) 220{ 221 *z = ( as17 & 0x10000 ) >> 16; 222 *x = ( as17 & 0x0f800 ) >> 11; 223 *y = ( ( as17 & 0x00400 ) >> 10 ) | ( ( as17 & 0x3ff ) << 1 ); 224} 225 226__private_extern__ 227uint32_t 228sign_unext( 229uint32_t x, 230uint32_t len) 231{ 232 uint32_t len_ones; 233 234 len_ones = ones(len); 235 return(x & len_ones); 236} 237 238__private_extern__ 239uint32_t 240dis_assemble_3( 241uint32_t x) 242{ 243 uint32_t r; 244 245 r = ( ( (x & 4 ) >> 2 ) | ( ( x & 3 ) << 1 ) ) & 7; 246 return(r); 247} 248 249__private_extern__ 250void 251dis_assemble_12( 252uint32_t as12, 253uint32_t *x, 254uint32_t *y) 255{ 256 *y = ( as12 & 0x800 ) >> 11; 257 *x = ( ( as12 & 0x3ff ) << 1 ) | ( ( as12 & 0x400 ) >> 10 ); 258} 259