|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* Copyright (c) 1996 NeXT Software, Inc. All rights reserved. ! 23: * ! 24: * File: architecture/ppc/pseudo_inst.h ! 25: * Author: Mike DeMoney ! 26: * ! 27: * This header file defines assembler pseudo-instruction macros for ! 28: * for the ppc. ! 29: * ! 30: * NOTE: This is obviously only useful to include in assembly ! 31: * code source. ! 32: * ! 33: * ALSO NOTE: These macros don't attempt to be 64-bit compatable ! 34: * ! 35: * HISTORY ! 36: * 29-Dec-96 Umesh Vaishampayan ([email protected]) ! 37: * Ported from m98k. ! 38: * 05-Nov-92 Mike DeMoney ([email protected]) ! 39: * Created. ! 40: */ ! 41: ! 42: #ifndef _ARCH_PPC_PSEUDO_INST_H_ ! 43: #define _ARCH_PPC_PSEUDO_INST_H_ ! 44: ! 45: #import <architecture/ppc/reg_help.h> ! 46: #import <architecture/ppc/asm_help.h> ! 47: ! 48: #ifdef __ASSEMBLER__ ! 49: ! 50: /* ! 51: * Pseudo instruction definitions ! 52: */ ! 53: ! 54: /* ! 55: * Macro package initialization ! 56: */ ! 57: .set __no_at,0 /* allow at by default */ ! 58: ! 59: /* ! 60: * .at_off -- disable use of at by macros ! 61: * .at_on -- enable use of at by macros ! 62: */ ! 63: .macro .at_off ! 64: .set __no_at,1 ! 65: .endmacro ! 66: ! 67: .macro .at_on ! 68: .set __no_at,0 ! 69: .endmacro ! 70: ! 71: /* ! 72: * li32 rD,IMMED ! 73: * ! 74: * Load 32-bit immediate into rD ! 75: * FIXME: Need a way to undefine built-in macro for this. ! 76: */ ! 77: .macro li32 // li32 rD,immed ! 78: .if $n != 2 ! 79: .abort "invalid operands of li32" ! 80: .endif ! 81: .abs __is_abs,$1 ! 82: .if !__is_abs ! 83: addis $0,0,hi16($1) ! 84: ori $0,$0,lo16($1) ! 85: .elseif $1 == 0 ! 86: addi $0,0,0 ! 87: .elseif ($1 & 0xffff) == 0 ! 88: addis $0,0,hi16($1) ! 89: .elseif ($1 & 0xffff8000) == 0 ! 90: addi $0,0,$1 ! 91: .elseif ($1 & 0xffff8000) == 0xffff8000 ! 92: addi $0,0,$1 ! 93: .else ! 94: addis $0,0,hi16($1) ! 95: ori $0,$0,lo16($1) ! 96: .endif ! 97: .endmacro ! 98: ! 99: ! 100: /* ! 101: * andi32. rD,rS1,IMMED ! 102: * ! 103: * Perform "andi." with (possibly) 32-bit immediate ! 104: */ ! 105: .macro andi32. // andi32. rD,rS1,IMMED ! 106: .if $n != 3 ! 107: .abort "invalid operands of andi." ! 108: .endif ! 109: .set __used_at,0 ! 110: .abs __is_abs,$2 ! 111: .if !__is_abs ! 112: .set __used_at,1 ! 113: li32 at,$2 ! 114: and. $0,$1,at ! 115: .elseif ($2 & 0xffff0000) == 0 ! 116: andi. $0,$1,$2 ! 117: .elseif ($2 & 0xffff) == 0 ! 118: andis. $0,$1,hi16($2) ! 119: .else ! 120: .set __used_at,1 ! 121: li32 at,$2 ! 122: and. $0,$1,at ! 123: .endif ! 124: .if __no_at & __used_at ! 125: .abort "Macro uses at while .no_at in effect" ! 126: .endif ! 127: .endmacro ! 128: ! 129: /* ! 130: * ori32 rD,rS1,IMMED ! 131: * ! 132: * Perform "ori" with (possibly) 32-bit immediate ! 133: */ ! 134: .macro ori32 // ori32 rD,rS1,IMMED ! 135: .if $n != 3 ! 136: .abort "invalid operands of ori" ! 137: .endif ! 138: .abs __is_abs,$2 ! 139: .if !__is_abs ! 140: oris $0,$1,hi16($2) ! 141: ori $0,$1,lo16($2) ! 142: .elseif ($2 & 0xffff0000) == 0 ! 143: ori $0,$1,$2 ! 144: .elseif ($2 & 0xffff) == 0 ! 145: oris $0,$1,hi16($2) ! 146: .else ! 147: oris $0,$1,hi16($2) ! 148: ori $0,$1,lo16($2) ! 149: .endif ! 150: .endmacro ! 151: ! 152: /* ! 153: * xori32 rD,rS1,IMMED ! 154: * ! 155: * Perform "xor" with (possibly) 32-bit immediate ! 156: */ ! 157: .macro xori32 // xori32 rD,rS1,IMMED ! 158: .if $n != 3 ! 159: .abort "invalid operands of xori" ! 160: .endif ! 161: .abs __is_abs,$2 ! 162: .if !__is_abs ! 163: xoris $0,$1,hi16($2) ! 164: xori $0,$1,lo16($2) ! 165: .elseif ($2 & 0xffff0000) == 0 ! 166: xori $0,$1,$2 ! 167: .elseif ($2 & 0xffff) == 0 ! 168: xoris $0,$1,hi16($2) ! 169: .else ! 170: xoris $0,$1,hi16($2) ! 171: xori $0,$1,lo16($2) ! 172: .endif ! 173: .endmacro ! 174: ! 175: ! 176: /* ! 177: * MEMREF_INST -- macros to memory referencing instructions ! 178: * "capable" of dealing with 32 bit offsets. ! 179: * ! 180: * NOTE: Because the assembler doesn't have any mechanism for easily ! 181: * parsing the d(rS) syntax of register-displacement form instructions, ! 182: * these instructions do NOT mirror the normal memory reference ! 183: * instructions. The following "transformation" is used: ! 184: * lbz rD,d(rS) ! 185: * becomes: ! 186: * lbz32 rD,rS,d ! 187: * I.e.: "32" is appended to the instruction name and the base register ! 188: * and displacement become the 2'nd and 3'rd comma-separated operands. ! 189: * ! 190: * The forms: ! 191: * lbz32 rD,d ! 192: * and: ! 193: * lbz32 rD,rS ! 194: * are also recognized and the missing operand is assumed 0. ! 195: * ! 196: * ALSO NOTE: r0 or zt should never be used as rS in these instructions. ! 197: * Use "0" as rS in this case. ! 198: */ ! 199: #define MEMREF_INST(op) \ ! 200: .macro op ## 32 @\ ! 201: .set __used_at,0 @\ ! 202: .if $n == 3 @\ ! 203: .greg __is_greg,$1 @\ ! 204: .abs __is_abs,$2 @\ ! 205: .if __is_abs @\ ! 206: .if ($2 & 0xffff8000) == 0 @\ ! 207: op $0,$2($1) @\ ! 208: .elseif ($2 & 0xffff8000) == 0xffff8000 @\ ! 209: op $0,$2($1) @\ ! 210: .else @\ ! 211: .if !__is_greg @\ ! 212: .set __used_at,1 @\ ! 213: lis at,ha16($2) @\ ! 214: op $0,lo16($2)(at) @\ ! 215: .else @\ ! 216: .set __used_at,1 @\ ! 217: lis at,ha16($2) @\ ! 218: add at,at,$1 @\ ! 219: op $0,lo16($2)(at) @\ ! 220: .endif @\ ! 221: .endif @\ ! 222: .else @\ ! 223: .if !__is_greg @\ ! 224: .set __used_at,1 @\ ! 225: lis at,ha16($2) @\ ! 226: op $0,lo16($2)(at) @\ ! 227: .else @\ ! 228: .set __used_at,1 @\ ! 229: lis at,ha16($2) @\ ! 230: add at,at,$1 @\ ! 231: op $0,lo16($2)(at) @\ ! 232: .endif @\ ! 233: .endif @\ ! 234: .elseif $n == 2 @\ ! 235: .greg __is_greg,$1 @\ ! 236: .if !__is_greg @\ ! 237: .abs __is_abs,$1 @\ ! 238: .if __is_abs @\ ! 239: .if ($1 & 0xffff8000) == 0 @\ ! 240: op $0,$1(0) @\ ! 241: .elseif ($1 & 0xffff8000) == 0xffff8000 @\ ! 242: op $0,$1(0) @\ ! 243: .else @\ ! 244: .set __used_at,1 @\ ! 245: lis at,ha16($1) @\ ! 246: op $0,lo16($1)(at) @\ ! 247: .endif @\ ! 248: .else @\ ! 249: .set __used_at,1 @\ ! 250: lis at,ha16($1) @\ ! 251: op $0,lo16($1)(at) @\ ! 252: .endif @\ ! 253: .else @\ ! 254: op $0,0($1) @\ ! 255: .endif @\ ! 256: .else @\ ! 257: .abort "Invalid operands of " #op "32" @\ ! 258: .endif @\ ! 259: .if __no_at & __used_at @\ ! 260: .abort "Macro uses at while .no_at in effect" @\ ! 261: .endif @\ ! 262: .endmacro ! 263: ! 264: MEMREF_INST(lbz) ! 265: MEMREF_INST(lhz) ! 266: MEMREF_INST(lha) ! 267: MEMREF_INST(lwz) ! 268: MEMREF_INST(lwa) ! 269: MEMREF_INST(ld) ! 270: ! 271: MEMREF_INST(stb) ! 272: MEMREF_INST(sth) ! 273: MEMREF_INST(stw) ! 274: MEMREF_INST(std) ! 275: ! 276: MEMREF_INST(lmw) ! 277: MEMREF_INST(lmd) ! 278: MEMREF_INST(stmw) ! 279: MEMREF_INST(stmd) ! 280: ! 281: /* ! 282: * ARITH_INST -- define 32-bit immediate forms of arithmetic ! 283: * instructions ! 284: * ! 285: * E.g. addi32 rD,rS,IMMED ! 286: */ ! 287: #define ARITH_INST(op, op3, sf) \ ! 288: .macro op ## 32 ## sf @\ ! 289: .if $n != 3 @\ ! 290: .abort "invalid operands to " #op "32" @\ ! 291: .endif @\ ! 292: .abs __is_abs,$2 @\ ! 293: .if __is_abs @\ ! 294: .if ($2 & 0xffff8000) == 0 @\ ! 295: op##sf $0,$1,$2 @\ ! 296: .elseif ($2 & 0xffff8000) == 0xffff8000 @\ ! 297: op##sf $0,$1,$2 @\ ! 298: .elseif __no_at @\ ! 299: .abort "Macro uses at while .no_at in effect" @\ ! 300: .else @\ ! 301: li32 at,$2 @\ ! 302: op3##sf $0,$1,at @\ ! 303: .endif @\ ! 304: .elseif __no_at @\ ! 305: .abort "Macro uses at while .no_at in effect" @\ ! 306: .else @\ ! 307: li32 at,$2 @\ ! 308: op3##sf $0,$1,at @\ ! 309: .endif @\ ! 310: .endmacro ! 311: ! 312: ARITH_INST(addi, add, ) ! 313: ARITH_INST(subi, sub, ) ! 314: ARITH_INST(addic, addc, ) ! 315: ARITH_INST(subic, subc, ) ! 316: ARITH_INST(addic, addc, .) ! 317: ARITH_INST(subic, subc, .) ! 318: ARITH_INST(mulli, mull, ) ! 319: ! 320: /* ! 321: * CMPEX_INST -- define 32-bit immediate forms of extended compare ! 322: * instructions ! 323: * ! 324: * E.g. cmpwi32 cr3,rS,IMMED ! 325: * cmpwi32 rS,IMMED ! 326: */ ! 327: #define CMPEX_INST(op, op3) \ ! 328: .macro op ## 32 @\ ! 329: .if $n == 3 @\ ! 330: .abs __is_abs,$2 @\ ! 331: .if __is_abs @\ ! 332: .if ($2 & 0xffff8000) == 0 @\ ! 333: op $0,$1,$2 @\ ! 334: .elseif ($2 & 0xffff8000) == 0xffff8000 @\ ! 335: op $0,$1,$2 @\ ! 336: .elseif __no_at @\ ! 337: .abort "Macro uses at while .no_at in effect" @\ ! 338: .else @\ ! 339: li32 at,$2 @\ ! 340: op3 $0,$1,at @\ ! 341: .endif @\ ! 342: .elseif __no_at @\ ! 343: .abort "Macro uses at while .no_at in effect" @\ ! 344: .else @\ ! 345: li32 at,$2 @\ ! 346: op3 $0,$1,at @\ ! 347: .endif @\ ! 348: .elseif $n == 2 @\ ! 349: .abs __is_abs,$1 @\ ! 350: .if __is_abs @\ ! 351: .if ($1 & 0xffff8000) == 0 @\ ! 352: op $0,$1 @\ ! 353: .elseif ($1 & 0xffff8000) == 0xffff8000 @\ ! 354: op $0,$1 @\ ! 355: .elseif __no_at @\ ! 356: .abort "Macro uses at while .no_at in effect" @\ ! 357: .else @\ ! 358: li32 at,$1 @\ ! 359: op3 $0,at @\ ! 360: .endif @\ ! 361: .elseif __no_at @\ ! 362: .abort "Macro uses at while .no_at in effect" @\ ! 363: .else @\ ! 364: li32 at,$1 @\ ! 365: op3 $0,at @\ ! 366: .endif @\ ! 367: .else @\ ! 368: .abort "invalid operands to " #op "32" @\ ! 369: .endif @\ ! 370: .endmacro ! 371: ! 372: CMPEX_INST(cmpdi, cmpd) ! 373: CMPEX_INST(cmpwi, cmpw) ! 374: CMPEX_INST(cmpldi, cmpld) ! 375: CMPEX_INST(cmplwi, cmplw) ! 376: ! 377: /* ! 378: * CMP_INST -- define 32-bit immediate forms of standard compare ! 379: * instructions ! 380: * ! 381: * E.g. cmpi32 cr3,0,rS,IMMED ! 382: */ ! 383: #define CMP_INST(op, op3) \ ! 384: .macro op ## 32 @\ ! 385: .if $n == 4 @\ ! 386: .abs __is_abs,$3 @\ ! 387: .if __is_abs @\ ! 388: .if ($3 & 0xffff8000) == 0 @\ ! 389: op $0,$1,$2,$3 @\ ! 390: .elseif ($3 & 0xffff8000) == 0xffff8000 @\ ! 391: op $0,$1,$2,$3 @\ ! 392: .elseif __no_at @\ ! 393: .abort "Macro uses at while .no_at in effect" @\ ! 394: .else @\ ! 395: li32 at,$3 @\ ! 396: op3 $0,$1,$2,at @\ ! 397: .endif @\ ! 398: .elseif __no_at @\ ! 399: .abort "Macro uses at while .no_at in effect" @\ ! 400: .else @\ ! 401: li32 at,$3 @\ ! 402: op3 $0,$1,$2,at @\ ! 403: .endif @\ ! 404: .else @\ ! 405: .abort "invalid operands to " #op "32" @\ ! 406: .endif @\ ! 407: .endmacro ! 408: ! 409: CMP_INST(cmpi, cmp) ! 410: CMP_INST(cmpli, cmpl) ! 411: ! 412: #endif /* __ASSEMBLER__ */ ! 413: ! 414: #endif /* _ARCH_PPC_PSEUDO_INST_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.