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