
.ifndef POWERPC_PPCMACROS_I
.set POWERPC_PPCMACROS_I, 1

#
#      $VER: PPCmacros.i 8.0 (3.6.97)
#
#      standard macros and definitions for PowerPC
#
#      ported to pasm by goocio/pht

.ifndef    __LOCALSIZE
.set __LOCALSIZE, 1024
.endif

.ifndef local
.set __LOCAL, 13
.set local,   13
.endif

.set base,  2
.set stack, 1
.set trash, 0

.set _d0, 3
.set _d1, 4
.set _d2, 22
.set _d3, 23
.set _d4, 24
.set _d5, 25
.set _d6, 26
.set _d7, 27
.set _a0, 5
.set _a1, 6
.set _a2, 28
.set _a3, 29
.set _a4, base
.set _a5, 30
.set _a6, 31

.set _fp0, 1
.set _fp1, 2
.set _fp2, 3
.set _fp3, 4
.set _fp4, 5
.set _fp5, 6
.set _fp6, 7
.set _fp7, 8

# NEAR mode is untested
.macro lw
			.ifeq    __MODE-__NEAR
				lwz     \1,\2(base)
			.else
				la      \1,\2
				lwz     \1,0(\1)
			.endif
.endm

.macro lh
			.ifeq    __MODE-__NEAR
				lhz     \1,\2(base)
			.else
				la      \1,\2
				lhz     \1,0(\1)
			.endif
.endm

.macro lhs
			.ifeq    __MODE-__NEAR
				lha     \1,\2(base)
			.else
				la      \1,\2
				lha     \1,0(\1)
			.endif
.endm

.macro lb
			.ifeq    __MODE-__NEAR
				lbz     \1,\2(base)
			.else
				la      \1,\2
				lbz     \1,0(\1)
			.endif
.endm

.macro lbs
			.ifeq    __MODE-__NEAR
				lbz     \1,\2(base)
				extsb   \1,\1
			.else
				la      \1,\2
				lbz     \1,0(\1)
				extsb   \1,\1
			.endif
.endm

.macro lf
			.ifeq    __MODE-__NEAR
				lfd     \1,\2(base)
			.else
				mr      trash,r3
				la      r3,\2
				lfd     \1,0(r3)
				mr      r3,trash
			.endif
.endm

.macro ls
			.ifeq    __MODE-__NEAR
				lfs     \1,\2(base)
			.else
				mr      trash,r3
				la      r3,\2
				lfs     \1,0(r3)
				mr      r3,trash
			.endif
.endm

.macro sw
			.ifeq    __MODE-__NEAR
				stw     \1,\2(base)
			.else
				mr      trash,\1
				la      \1,\2
				stw     trash,0(\1)
				mr      \1,trash
			.endif
.endm

.macro sh
			.ifeq    __MODE-__NEAR
				sth     \1,\2(base)
			.else
				mr      trash,\1
				la      \1,\2
				sth     trash,0(\1)
				mr      \1,trash
			.endif
.endm

.macro sb
			.ifeq    __MODE-__NEAR
				stb     \1,\2(base)
			.else
				mr      trash,\1
				la      \1,\2
				stb     trash,0(\1)
				mr      \1,trash
			.endif
.endm

.macro sf
			.ifeq    __MODE-__NEAR
				stfd    \1,\2(base)
			.else
				mr      trash,r3
				la      r3,\2
				stfd    \1,0(r3)
				mr      r3,trash
			.endif
.endm

.macro ss
			.ifeq    __MODE-__NEAR
				stfs    \1,\2(base)
			.else
				mr      trash,r3
				la      r3,\2
				stfs    \1,0(r3)
				mr      r3,trash
			.endif
.endm

.macro lba
		lbz     \1,\2
		extsb   \1,\1
.endm

.macro lbau
		lbzu    \1,\2
		extsb   \1,\1
.endm

.macro lbax
		lbzx    \1,\2,\3
		extsb   \1,\1
.endm

.macro lbaux
		lbzux   \1,\2,\3
		extsb   \1,\1
.endm

.macro stwi
		liw     trash,\1
		stw     trash,\2
.endm

.macro sthi
		li      trash,\1
		sth     trash,\2
endm

.macro stbi
		li      trash,\1
		stb     trash,\2
.endm

.macro stwiu
		liw     trash,\1
		stwu    trash,\2
.endm

.macro sthiu
		li      trash,\1
		sthu    trash,\2
.endm

.macro stbiu
		li      trash,\1
		stbu    trash,\2
.endm

.macro stwix
		liw     trash,\1
		stwx    trash,\2,\3
.endm

.macro sthix
		li      trash,\1
		sthx    trash,\2,\3
.endm

.macro stbix
		li      trash,\1
		stbx    trash,\2,\3
.endm

.macro stwiux
		liw     trash,\1
		stwux   trash,\2,\3
.endm

.macro sthiux
		li      trash,\1
		sthux   trash,\2,\3
.endm

.macro stbiux
		li      trash,\1
		stbux   trash,\2,\3
.endm

.macro swi
			.ifeq    __MODE-__NEAR
				liw     trash,\1
				stw     trash,\2(base)
			.else
				stw     r3,-4(local)
				liw     trash,\1
				la      r3,\2
				stw     trash,0(r3)
				lwz     r3,-4(local)
			.endif
.endm

.macro shi
			.ifeq    __MODE-__NEAR
				li      trash,\1
				sth     trash,\2(base)
			.else
				stw     r3,-4(local)
				li      trash,\1
				la      r3,\2
				sth     trash,0(r3)
				lwz     r3,-4(local)
			.endif
.endm

.macro sbi
			.ifeq    __MODE-__NEAR
				li      trash,\1
				stb     trash,\2(base)
			.else
				stw     r3,-4(local)
				li      trash,\1
				la      r3,\2
				stb     trash,0(r3)
				lwz     r3,-4(local)
			.endif
.endm

# ignore warning 30 if occured in liw macro
.macro liw
		lis     \1,(\2&0xffff0000)>>16
		ori     \1,\1,\2&0xffff
.endm

.macro clrw
		xor\0   \1,\1,\1
.endm

.macro clrh
		clrrwi\0 \1,\1,16
.endm

.macro clrb
		clrrwi\0 \1,\1,8
.endm

.macro setb
		ori     \1,\1,$ff
.endm

.macro seth
		ori     \1,\1,$ffff
.endm

.macro setw
		eqv\0   \1,\1,\1
.endm

.macro mh
		insrwi\0 \1,\2,16,16
.endm

.macro mb
		insrwi\0 \1,\2,8,24
.endm

.macro tstb
		extsb.  trash,\1
.endm

.macro tsth
		extsh.  trash,\1
.endm

.macro tstw
		mr.     \1,\1
.endm

.macro bittst
		.iflt    (\2)-31
			extrwi. trash,\1,1,\2
		.else
			andi.   trash,\1,$1
		.endif
.endm

.macro bitset
		.iflt    (\2)-16
			oris    \1,\1,(1<<(15-(\2)))
		.else
			ori     \1,\1,(1<<(31-(\2)))
		.endif
.endm

.macro bitclr
		.iflt    (\2)-16
			oris    \1,\1,(1<<(15-(\2)))
			xoris   \1,\1,(1<<(15-(\2)))
		.else
			ori     \1,\1,(1<<(31-(\2)))
			xori    \1,\1,(1<<(31-(\2)))
		.endif
.endm

.macro bitchg
		.iflt    (\2)-16
			xoris   \1,\1,(1<<(15-(\2)))
		.else
			xori    \1,\1,(1<<(31-(\2)))
		.endif
.endm

.macro
		stwu    \1,-4(local)
		endm
.endm

.macro pushf
		stfdu   \1,-8(local)
		endm
.endm

.macro pushlr
		mflr    trash
		stwu    trash,-4(local)
		endm
.endm

.macro pushctr
		mfctr   trash
		stwu    trash,-4(local)
.endm

.macro pushcr
		mfcr    trash
		stwu    trash,-4(local)
.endm

.macro pop
		lwz     \1,0(local)
		addi    local,local,4
.endm

.macro popf
		lfd     \1,0(local)
		addi    local,local,8
.endm

.macro poplr
		lwz     trash,0(local)
		addi    local,local,4
		mtlr    trash
.endm

.macro popctr
		lwz     trash,0(local)
		addi    local,local,4
		mtctr   trash
.endm

.macro popcr
		lwz     trash,0(local)
		addi    local,local,4
		mtcr    trash
.endm

.macro lnk
		stwu    \1,-4(local)
		mr      \1,local
		addi    local,local,\2
.endm

.macro ulnk
		mr      local,\1
		lwz     \1,0(local)
		addi    local,local,4
.endm

# assumes that the second argument is a number (without preceding r)
.macro setlocal
  .set __LOCALSIZE, \1
  .set __LOCAL, \2
  .set local, \2
.endm

# necessary as pasm's macros don't support string arguments
.set TOC,1

.macro prolog
    .ifge   $NARG-2
      .set local, \2
      .set __LOCAL, \2
    .endif
    .ifge   $NARG-3
      .ifeq     TOC-\3
        stw     base,20(stack)
      .endif
    .endif
    mflr    trash
    stw     trash,8(stack)
    mfcr    trash
    stw     trash,4(stack)
    stw     local,-4(stack)
    subi    local,stack,4
    .iflt   $NARG-1
      .set __ARGS,   24+4+(__LOCALSIZE)+56
      stwu    stack,-((__ARGS)-56)(stack)
    .else
      .set __ARGS,   24+4+(\1)+56
      stwu    stack,-((__ARGS)-56)(stack)
    .endif
.endm

.macro epilog
    lwz     stack,0(stack)
    lwz     local,-4(stack)
    lwz     trash,8(stack)
    mtlr    trash
    lwz     trash,4(stack)
    mtcr    trash

    .ifge   $NARG-1
      .ifeq   TOC-\1
        lwz     base,20(stack)
      .endif
    .endif
    blr
.endm


.endif # .ifndef POWERPC_PPCMACROS_I
