[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

 

Chapter 10.

 

PowerPC Assembler



This chapter describes support for assembly language programming built into the CodeWarrior compilers. From your C/C++ source code files you use the assembly language features that the CodeWarrior compilers will translate into object code.

This chapter does not discuss the stand-alone assembler available for PowerPC. For information on the stand-alone assembler, see the Assembler Reference.

This chapter does not document all the instructions available in assembly language. For general information on PowerPC assembly language instructions, see PowerPC Microprocessor Family: The Programming Environment for 32-Bit Microprocessors, published by Motorola (serial number MPCFPE32B/AD).

You can find this and other useful published information on the world-wide web at this address :

http://motorola.com/SPS/PowerPC/teksupport/teklibrary/index.html

The sections in this chapter are:


Working With Assembly

This section describes how to use the CodeWarrior compiler's built-in support for assembly language programming, including assembler syntax.

The topics in this section are:


Assembler Syntax for PowerPC

To specify that a block of code in your file should be interpreted as assembly language, use the asm keyword.


NOTE

To ensure that the C/C++ compiler recognizes the asm keyword, you must turn off the ANSI Strict and ANSI Keywords Only options in the C/C++ Language settings panel. This panel and its options are fully described in the IDE User Guide or the C Compilers Reference.


The assembly instructions are the standard PowerPC instruction mnemonics. For more information on PowerPC assembly language instructions, see PowerPC Microprocessor Family: The Programming Environment for 32-Bit Microprocessors, published by Motorola (serial number MPCFPE32B/AD).

There are two ways to use assembly language with the Metrowerks compilers.

First, you can write code to specify that an entire function is in assembly language. This is called function-level assembly language. Alternatively, assembly statement blocks within a function are also supported. In other words, you can write code that is both in function-level assembly language and statement-level assembly language.


TIP

To enter a few lines of assembly language code within a single function, you can use the compiler's support for intrinsics. Intrinsics are an alternative to using asm statements within functions. See "Intrinsic Functions."


Function-level assembly code for PowerPC uses the following syntax:


asm {function definition }

For example:


asm long MyFunc(void) // OK, an assembly function
{
 . . . // assembly instructions
}

However, the following statement-level code is also permitted:


long MyFunc (void)
{
 asm {. . .} // inline assembly statement blocks are now supported
}


NOTE

Assembly language functions are never optimized, regardless of compiler settings.


Statement-level assembler syntax has the following form:


asm { one or more instructions }

You can use an asm statement wherever a code statement is allowed.


NOTE

Functions that contain an asm block are only partially optimized, as the function itself will be optimized, but the optimizer will skip any asm blocks of code.


The built-in assembler uses all the standard PowerPC assembler instructions. It accepts some additional directives described in "Assembler Directives." If you use the machine directive, you can also use instructions that are available only in certain versions of the PowerPC. For more information, see "machine."

Keep these tips in mind as you write assembly functions:

Each instruction must end with a newline or a semicolon (;).

Hex constants must be in C-style, not Pascal-style. For example:


li  r3, 0xABCDEF   // OK
li  r3, $ABCDEF   // ERROR

Assembler directives, instructions, and registers are case-sensitive and must be in lowercase. For example these two statements are different:
add  r2,r3,r4    // OK
ADD  R2,R3,R4     // ERROR

Every assembly function must end in an blr statement if you use frfree. The compiler does not add one for you. For example:
asm void f(void)
{
	fralloc
  add r2,r3,r4
	frfree
}         // SEMANTIC ERROR: No blr statement
asm void g(void)
{
	fralloc
  add r2,r3,r4
	frfree
	blr      // OK
}

Listing 10.1 shows an example of an assembly function.

Creating an assembly function:


asm void mystrcpy(register char *tostr, register char *fromstr);
asm void mystrcpy(register char *tostr, register char *fromstr)
{
  addi  tostr,tostr,-1
  addi  fromstr,fromstr,-1
@1 lbzu  r5,1(fromstr)
  cmpwi r5,0
  stbu  r5,1(tostr)
  bne  @1
}


Special PowerPC Instructions

To set the branch prediction (y) bit for those branch instructions that can use it, use + or -. For example:


@1 bne+  @2  // Predicts branch taken
@2 bne-  @1  // Predicts branch not taken

Most integer instructions have four different forms:

Some instructions only have a record form (with a period). Make sure to include the period always:


andi. r3,r4,7  // '.' is not optional here
andis. r3,r4,7  // Or here
stwcx. r3,r4,r5 // Or here


Support for AltiVec Instructions

The full set of AltiVec assembly instructions is now supported in your inline assembly code. Refer to the manual entitled AltiVec Technology Programming Interface Manual, Rev. 1, on the Motorola web site for more information about AltiVec instructions.


NOTE

You would have to specify the machine altivec directive or its equivalent, refer to "machine" for more information.


You can also use intrinsics in your code, refer to "Intrinsic Functions" for more information on this topic.


Creating Labels for PowerPC Assembly

A label can be any identifier that you haven't already declared as a local variable. The name may start with @, so these are legal names: foo, @foo, and @1. Only labels that don't start with @ need to end in a colon. For example:


asm void foo(void)
{
x1: add  r3,r4,r5   // OK, has colon
@x2: add  r6,r7,r8   // OK, has both @ and colon
x3  add  r9,r10,r11  // ERROR, Needs colon
@x4 add  r12,r13,r14  // OK, starts with @
}


NOTE

The first statement in an assembly function cannot be a label that starts with @.



Using Comments in PowerPC Assembly

You cannot begin comments with a pound sign (#), since the preprocessor uses the pound sign. However, you can use C and C++ comments. For example:


add  r3,r4,r5  # ERROR
add  r3,r4,r5  // OK
add  r3,r4,r5  /* OK */


Using the Preprocessor in PowerPC Assembly

You can use all preprocessor features, such as comments and macros, in the assembler. However you must end each assembly statement with a semicolon (;), because the preprocessor ignores newlines. For example:


#define remainder(x,y,z) \
divw  z,x,y; \
mullw  z,z,y; \
subf  z,z,x
asm void newPointlessMath(void)
{
	remainder(r3,r4,r5)
}


Using Local Variables and Arguments in PowerPC Assembly

To refer to a memory location, you can use the name of a local variable or argument.


NOTE

You can refer to local variables by name even if a function does not contain the fralloc directive. You can read more about fralloc in the section entitled "Creating a Stack Frame in PowerPC Assembly."


The rule for assigning arguments to registers or memory depends on whether the function has a stack frame. If function has a stack frame, the in-line assembler assigns:

If function has no stack frame, the in-line assembler assigns:

arguments that are declared register and passed in registers to the appropriate register other arguments to memory locations all locals to memory locations


NOTE

If there is no stack frame, a function cannot have more than 224 bytes of local variables.


For more information on PowerPC register conventions and argument-passing conventions, see "C and C++ Support for Power PC."


Creating a Stack Frame in PowerPC Assembly

You need to create a stack frame for a function, if the function:

The easiest way to create a stack frame is to use the fralloc directive at the beginning of your function and the frfree directive just before the blr statement at the end. The fralloc directive automatically allocates and de-allocates memory for local variables and saves and restores the register contents. Note that frfree can only be used at the end of an assembly function. To exit a function from the middle, you must branch to frfree at the end of the function (this is exactly how the compiler generates exit points in the middle of a function) as shown in the example below.


asm void foo ()
{
    fralloc
    // Your code here
    b   theend      // to exit from the middle, branch to frfree
    // More of your code
theend:
    frfree // must specify blr if you use frfree
    blr     // this instruction returns you to the calling function
}


NOTE

If you use frfree you must follow it with a blr instruction. Otherwise you will end up running code from an unspecified address.


The fralloc directive has an optional argument number which lets you specify the size in bytes of the parameter area of the stack frame. The stack frame is an area for storing parameters used by the assembly code. By default, the compiler creates a 32-byte parameter area for you to pass variables into your assembly language functions. If your assembly-language routine calls any function that takes more than 32 bytes of parameters, you must specify a larger amount.In PowerPC, function arguments are passed using registers. In the case of integer values, registers r3-r10 are used. Local variables are where the parameters will be stored that the registers will point to.

As an example, if you pass 4 long integers to your assembly function, this would consume 16 bytes of the parameter area.


Specifying Operands in PowerPC Assembly

This topic describes how to specify the operands for assembly language instructions. It discusses how to use registers, labels, variable names, and immediate operands.


Using registers

For a register operand, you must use one of the register names of the appropriate kind for the instruction. The register names are case-sensitive. You can also use a symbolic name for an argument or local variable that was assigned to a register.

The general registers for PowerPC are RTOC, SP, r0 to r31, and gpr0 to gpr31. The floating-point registers are fp0 to fp31 and f0 to f31. The condition registers are cr0 to cr7.

Assembly language mnemonics which take registers as operands which need to access local variables or paramters need to have the parameters or local variables declared as register type:


register int a;


AltiVec Function Calls with a Fixed Number of Arguments

The first twelve parameters of any non-struct vector data type are placed in consecutive vector registers v2 through v13. Any additional vector-typed parameters are passed through memory on the stack. They appear together, 16-byte aligned, and after any non-vector parameters. If fewer (or no) vector type arguments are passed, the unneeded registers are not loaded and will contain undefined values on entry to the called function.

Non-vector parameters are passed in the same registers as they would be if the vector parameters were not present. Structs that contain vector fields are treated the same as any other struct except that they are 16-byte aligned. This can result in words in the parameter list being skipped for alignment (padding) and left with undefined value.

Vector parameters are not shadowed in GPR's. They are not placed in memory unless there are more than 12 vector arguments. Functions that declare a vector data type as a return value place that return value in register v2.


Using labels

For a label operand, you can use the name of a label. For long branches (such as b and bl instructions) you can also use function names. For bla and la instructions, you use absolute addresses. For other branches, you must use the name of a label. For example:


b  @3  // OK: Branch to local label
b  foo  // OK: Branch to external function foo
bl  @3  // OK: Call local label
bl  foo  // OK: Call external function foo
bne foo  // ERROR: Short branch outside function

You can also use label differencing. addi, subi, li, addis and opword all now support this feature. The syntax goes like this:


<label> `-' <label {`+'|'-' <constant expr>]

Here is an example:


label1:
	addi r5, r5, label2 - label1 + 16
label2:


Using variable names as memory locations

Whenever an instruction requires a memory location (such as a load instruction, a store instruction, or la), you can use a local or global variable name. You can modify local variable names with struct member references, class member references, array subscripts, or constant displacements. For example, all of the following are valid local variable references:


asm void foo(void)
{
	long myVar;
	long myArray[1];
	Rect myRectArray[3];
	lwz r3,myVar(SP) // load myVar into r3
	la  r3,myVar(SP) // load address of myVar into r3
	lwz r3,myRect.top
	lwz r3,myArray[2](SP)
	lwz r3,myRectArray[2].top
	lbz r3,myRectArray[2].top+1(SP)
}

You may also use a register variable that is a pointer to a struct or class to access a member of the struct. For example:


void foo(void)
{
	register Rect *p;
	asm {
		lwz r3,p->top;
	}
}

You can use the @hiword and @loword directives to access parts of a variable defined long long, as shown in Listing 10.2:

Using the @ Symbol:


long long gTheLongLong = 5;
asm void Foo(void);
asm void Foo(void)
{
	fralloc

	lwz r5, gTheLongLong@hiword // the upper word of gTheLongLong
	lwz r6, gTheLongLong@loword // the lower word of gTheLongLong

	frfree // if using frfree, you must specific blr
	blr     // returns to the calling function
}

This allows you to access the specific part of a register pair.


Using immediate operands

For an immediate operand, you can use an integer or enum constant, sizeof expression, and any constant expression using any of the C dyadic and monadic arithmetic operators. These expressions follow the same precedence and associativity rules as normal C expressions. The in-line assembler carries out all arithmetic with 32-bit signed integers.

An immediate operand can also be a reference to a member of a struct or class type. You can use any struct or class name from a typedef statement, followed by any number of member references. This evaluates to the offset of the member from the start of the struct. For example:


lwz  r4,Rect.top(r3)
addi r6,r6,Rect.left

As a side note, this line:


la rD,d(rA)

is the same as this line:


addi rD,rA,d

You can also use the top or bottom half-word of an immediate word value as an immediate operand. To do this, use one of the @ modifiers, as illustrated below:


long gTheLong;
asm void foo(void)
{
	fralloc

	ori r6, gTheLong@ha //upper halfword of address of "gTheLong"
	ori r7, gTheLong@h //upper halfword of address of "gTheLong"
	addi r7, gTheLong@l //lower halfword of address of "gTheLong"

	frfree // if using frfree, you must specify blr
	blr     // returns to the calling function
}

The preferred technique is exemplified here:


long gTheLong;
asm void foo(void)
{
	fralloc
	lwz r7,gTheLong(RTOC)
	frfree // if using frfree, you must specify blr
	blr     // returns to the calling function
}

However the access patterns are:


	lis	x,var@ha
	la	x,var@l(x)

or


	lis	x,var@h
	ori	x,x,var@l

In this example, la is the simplified form of addi to load an address. las is like la but shifted. Refer to the Motorola PowerPC manuals for more information.

Using @ha is preferred since you can write:


	lis	x,var@ha
	lwz	v,var@l(x)

which you can't do with @h because it requires that you use the ori instruction.

This is the simplified form to accessing globals:


void foo(void)
{
	register long *addr = &gTheLong;
	asm {
		.... use addr for r7 ....
	}
}


Embedding opword Instructions

You can directly embed instructions in code using hex numbers as shown here:


asm {
	opword 0x60000000 // embed a nop
}


Assembler Directives

This section describes special assembler directives that the PowerPC built-in assembler accepts. They are:


entry


  entry [ extern | static ] name

PowerPC assembler directive that defines an entry point into the current function. Use the extern qualifier to declare a global entry point and use the static qualifier to declare a local entry point. If you leave out the qualifier, extern is assumed.

Using the entry directive:


void __save_fpr_15(void);
void __save_fpr_16(void);
asm void __save_fpr_14(void)
{
  stfd  fp14,-144(SP)
entry 				__save_fpr_15
  stfd  fp15,-136(SP)
entry 				__save_fpr_16
  stfd fp16,-128(SP)
  // ...
	blr // returns to the calling function
}


fralloc


  fralloc [ number ]

PowerPC assembler directive that creates a stack frame for a function and reserves registers for your local register variables. You need to create a stack frame, if the function

You don't need to use fralloc if you use non-volatile registers as long as you save them yourself.

For more information, see "Creating a Stack Frame in PowerPC Assembly."

The fralloc directive has an optional argument number which lets you specify the size in bytes of the parameter area of the stack frame. By default, the compiler creates a 32-byte parameter area. If your assembly-language routine calls any function that takes more than 32 bytes of parameters, you must specify a larger amount.

Using fralloc does not require frfree to be put at the end of functions. If you do use frfree then add blr after it.


Argument Passing

Integers are passed using registers like r3, and r4. AltiVec vector arguments are passed differently as discussed here.

The first twelve parameters of any non-struct vector data type are placed in consecutive vector registers v2 through v13. Any additional vector-typed parameters are passed through memory on the stack. They appear together, 16-byte aligned, and after any non-vector parameters. If fewer (or no) vector type arguments are passed, the unneeded registers are not loaded and will contain undefined values on entry to the called function.

Non-vector parameters are passed in the same registers as they would be if the vector parameters were not present. Structs that contain vector fields are treated the same as any other struct except that they are 16-byte aligned. This can result in words in the parameter list being skipped for alignment (padding) and left with undefined values.

Vector parameters are not shadowed in GPR's. They are not placed in memory unless there are more than 12 vector arguments.

Functions that declare a vector data type as a return value place that return value in register v2.


frfree


  frfree

PowerPC assembler directive that frees the stack frame and restores the registers that fralloc reserved. frfree can only be used at the end of an assembly function. To exit a function from the middle, you must branch to frfree at the end of the function. For more information, see "Creating a Stack Frame in PowerPC Assembly."


NOTE

If you use frfree you must follow it with a blr instruction. Otherwise you will end up running code from an unspecified address.


Using fralloc does not require frfree to be put at the end of functions. If you do use frfree then always add blr after it.


machine


  machine number

PowerPC assembler directive that specifies which CPU the assembly code is for. The number must be one of the following:

601  
602  
603  
604  
750  
7400  
all  
generic  
PPC603e  
PPC604e  
altivec  
 

If you use all, you can use only those instructions that are available on all PowerPC CPUs. If you don't use the machine directive, the compiler assumes all.

For example:


machine altivec

This enables the assembler AltiVec instructions. Note that:


 #pragma altivec_codegen on 

has the same effect.

If you use machine 601, the following instructions, formerly known as the POWER instructions, are deprecated:

abs  
abs.  
abso  
abso.  
clcs  
div  
div.  
divo  
divo.  
doz  
doz.  
dozo  
dozo.  
dozi  
lscbx  
lscbx.  
maskg  
maskg.  
markir  
markir.  
mul  
mul.  
mulo  
mulo.  
nabs  
nabs.  
nabso  
nabso.  
rlmi  
rlmi.  
rrib  
rrib.  
sle  
sle.  
sleq  
sleq.  
sliq  
sliq.  
slliq  
slliq.  
sllq  
sllq.  
slq  
slq.  
sraig  
sraig.  
sraq  
sraq.  
sre  
sre.  
srea  
srea.  
sreq  
sreq.  
sriq  
sriq.  
srliq  
srliq.  
srlq  
srlq.  
srq  
srq.  
tlbie  
 
 

If you use 603 or 604, you may also use the following instructions:

fres  
fres.  
frsqrte  
frsqrte.  
fsel  
fsel.  
mftb  
mftbl  
stfiwx  
tlbld  
tlbli  
tlbsync  
 
 
 


nofralloc

This allows you to suppress prolog generation. In this case you are required to setup the prolog correctly yourself.


asm void foo_asm(void) {
	nofralloc
	... more code
	blr // returns to the calling function
}


Intrinsic Functions

This section discusses support for intrinsic functions in the CodeWarrior compilers. Support for intrinsic functions is not part of the ANSI C or C++ standards. They are an extension provided by the CodeWarrior compilers.

Intrinsic functions are one mechanism you can use to get assembly language into your source code. Here's how intrinsic functions work.

There is an intrinsic function for each processor opcode (instruction). Rather than using inline assembly syntax and specifying the opcode in an asm block, you call the intrinsic function that matches the opcode.

When the compiler encounters the intrinsic function call in your source code, it doesn't actually make a function call. The compiler substitutes the assembly instruction that matches your function call. As a result, no function call occurs in the final object code. The final code is the assembly language instructions that correspond to the intrinsic functions.


TIP

You can use intrinsic functions or the asm keyword to add a few lines of assembly code within a function. If you want to write an entire function in assembly, you can also use the inline assembler. See "Working With Assembly."


For additional information on PowerPC assembly language instructions, see PowerPC Microprocessor Family: The Programming Environment for 32-Bit Microprocessors, published by Motorola (#MPCFPE32B/AD R1).

See also: "Working With Assembly."

The topics in this section are:


Low-Level Processor Synchronization

These functions perform low-level processor synchronization.


void __eieio(void) /* Enforce In-Order Execution of I/O */
void __sync(void) /* Synchronize */
void __isync(void) /* Instruction Synchronize */

For more information on these functions, see the instructions eieio, sync, and isync in PowerPC Microprocessor Family: The Programming Environments by Motorola.


Floating-Point Functions

These functions generate inline instructions that take the absolute value of a number.


int __abs(int);    /* Absolute value of an integer */
float __fabs(float); /* Absolute value of a float */
float __fnabs(float); /* Negative absolute value of a float */

long __labs(long);  /* Absolute value of a long int */


Byte-Reversing Functions

These functions generate inline instructions than can dramatically speed up certain code sequences, especially byte-reversal operations:


int __lhbrx(void *, int); /* Load halfword byte - reverse index */
int __lwbrx(void *, int); /* Load word byte - reverse index */

void __sthbrx(unsigned short, void *, int);
         /* Store halfword byte - reverse index */

void __stwbrx(unsigned int, void *, int);
         /* Store word byte - reverse indexed */

However, these intrinsics are now created as having side effects and will never be optimized away.


Setting the Floating-Point Environment

This function lets you change the PowerPC processor's Floating Point Status and Control Register (FPSCR). It sets the FPSCR to its argument and returns the original value of the FPSCR.


float __setflm(float);

This example shows how to set and restore the FPSCR:


double old_fpscr;
oldfpscr = __setflm(0.0); /* Clear all flag/exception/mode bits 
               and save the original settings */
/* Peform some floating point operations */

__setflm(old_fpscr); /* Restore the FPSCR */


Manipulating the Contents of a Variable or Register

These functions rotate the contents of a variable to the left.


int __rlwinm(int, int, int, int);
 /* Rotate Left Word Immediate, then AND with Mask */
int __rlwnm(int, int, int, int);
 /* Rotate Left Word, then AND with Mask */

int __rlwimi(int, int, int, int, int);
 /* Rotate Left Word Immediate then Mask Insert */

Please note that the first argument to __rlwimi is usually overwritten. However, if the first parameter is a local variable allocated to a register, then it is both an input and output parameter. For this reason, this intrinsic should always be written to put the result in the same variable as the first parameter as shown here:


ra = __rlwimi( ra, rs, sh, mb, me );

You may count the leading zeros in a register with this one:


int __cntlzw(int);    /* Count leading zeros in a integer */


TIP

You can use inline assembly for a complete assembly language function, as well as individual assembly statements. See "Working With Assembly."



Usage Warning for __rlwinm

When the __rlwimi intrinsic is used within an inline function it can violate C syntax by modifying the first parameter passed by value if its stored in a register. Because of this non-conformist behavior, there is no good way to modify the C compiler to allow maximum benefit of the intrinsic. Since this behavior can also be not obvious, it can cause problems when writing your code.

Specifically, if an inline function calls __rlwini and it does not want the input parameter to the function overwritten, the user should assign the input to the result before calling __rlwini. To prevent the possible overwriting of the input value they must do something like the following:


int inline mask_insert(int input, int value)
{
	int	Result = input;
	result = __rlwimi(result, value, 0, 16, 31);
	return(result);
}

The reason for having this nasty instrinsic is so you can use the side effect:


int inline swapbytes(int input)
{
	int result = __rlwinm(input,8,24,31);
	result = __rlwimi(result,input,24,16,23);
	result = __rlwimi(result,input,8,8,15);
	result = __rlwimi(result,input,24,0,7);
	return(result);
}

There is no way for the inliner to know that __rlwimi is an invalid function so it does copy propagation (to remove wasted copies). The only way to make this example work right is to force __rlwimi() to copy it's input value into a temp register which will hold the result. This however will break the code of people who have not updated their source to use the correct form.

Instead of depending upon the __rlwimi side-effect of value overwriting by doing this:


int inline swapbytes(int input)
{
	int result = __rlwinm(input,8,24,31);
	__rlwimi(result,input,24,16,23);
	__rlwimi(result,input,8,8,15);
	__rlwimi(result,input,24,0,7);
	return(result);
}

You should be using the statement level assembler like this:


int inline mask_insert(register int input)
{
	register int	value = 0xC0DE;
	asm {
		rlwimi input, value, 0, 16, 31
	}
	return input;
}

To prevent the problem from ever appearing.


Data Cache Manipulation

The intrinsics shown in Table 10.1 map directly to PowerPC assembly instructions.

 

Instrinsic Prototype
PowerPC Instruction
void __dcbf(void *, int);  
dcbf  
void __dcbt(void *, int);  
dcbt  
void __dcbst(void *, int);  
dcbst  
void __dcbtst(void *, int);  
dcbtst  
void __dcbz(void *, int);  
dcbz  

Data Cache Instrinsics:

Math Functions

The intrinsics shown in Table 10.2 map directly to PowerPC assembly instructions.

Math Intrinsics:

 

Intrinsic Prototype
PowerPC Instruction
int __mulhw(int, int);  
mulhw  
uint __mulhwu(uint, uint);  
mulhwu  
double __fmadd(double, double, double);  
fmadd  
double __fmsub(double, double, double);  
fmsub  
double __fnmadd(double, double, double);  
fnmadd  
double __fnmsub(double, double, double);  
fnmsub  
float __fmadds(float, float, float);  
fmadds  
float __fmsubs(float, float, float);  
fmsubs  
float __fnmadds(float, float, float);  
fnmadds  
float __fnmsubs(float, float, float);  
fnmsubs  
double __mffs(void);  
mffs  
float __fabsf(float);  
fabsf  
float __fnabsf(float);  
fnabsf  


Buffer Manipulation

Some intrinsics allow control over areas of memory, so you can manipulate memory blocks.


void *__alloca(ulong);

__alloca implements alloca() in the compiler.


char *__strcpy(char *, const char *);

__strcpy() detects copies of constant size and calls __memcpy(). This intrinsic requires that a __strcpy function be implemented because if the string is not a constant it will call __strcpy to do the copy.


void *__memcpy(void *, const void *, size_t);

__memcpy() provides access to the block move in the code generator to do the block move inline.


AltiVec Intrinsics Support

You can use many AltiVec intrinsics in your code as you would any other intrinsic. You will find a list of the supported intrinsics in the relevant Motorola documentation at this URL on the world-wide web:

http://www.mot.com/SPS/PowerPC/teksupport/teklibrary/manuals/altivecpim.pdf

A table of these intrinsics is shown here as Table 10.3 and Table 10.4 for reference.


NOTE

Note that you can't overload the names. Other specifications for the AltiVec programming interface may refer to overloading, which is not supported in this implementation.


AltiVec Generic and Specific Intrinsics :

 

vec_abs  
vec_abss  
vec_add  
vec_addc  
vec_adds  
vec_and  
vec_andc  
vec_avg  
vec_ceil  
vec_cmpb  
vec_cmpeq  
vec_cmpge  
vec_cmpgt  
vec_cmple  
vec_cmplt  
vec_ctf  
vec_cts  
vec_ctu  
vec_dss  
vec_dssall  
vec_dst  
vec_dstst  
vec_dstt  
vec_expte  
vec_floor  
vec_ld  
vec_lde  
vec_ldl  
vec_loge  
vec_lvsl  
vec_lvsr  
vec_madd  
vec_madds  
vec_max  
vec_mergeh  
vec_merge  
vec_mfvscr  
vec_min  
vec_mladd  
vec_mradds  
vec_msum  
vec_msums  
vec_mtvscr  
vec_mule  
vec_mulo  
vec_nmsub  
vec_nor  
vec_or  
vec_pack  
vec_packpx  
vec_packs  
vec_packsu  
vec_perm  
vec_re  
vec_rl  
vec_round  
vec_rsqrte  
vec_sel  
vec_sl  
vec_sld  
vec_sll  
vec_slo  
vec_splat  
vec_splat_s8  
vec_splat_s16  
vec_splat_s32  
vec_splat_u8  
vec_splat_u16  
vec_splat_u32  
vec_sr  
vec_sra  
vec_srl  
vec_sro  
vec_st  
vec_ste  
vec_stl  
vec_sub  
vec_subc  
vec_subs  
vec_sum4s  
vec_sum2s  
vec_sums  
vec_trunc  
vec_unpackh  
vec_unpackl  
vec_xor  
 
 

AltiVec Predicates :

 

vec_all_eq  
vec_all_ge  
vec_all_gt  
vec_all_in  
vec_all_le  
vec_all_lt  
vec_all_nan  
vec_all_ne  
vec_all_nge  
vec_all_ngt  
vec_all_nle  
vec_all_nlt  
vec_all_numeric  
vec_any_eq  
vec_any_ge  
vec_any_gt  
vec_any_le  
vec_any_lt  
vec_any_nan  
vec_any_ne  
vec_any_nge  
vec_any_ngt  
vec_any_nle  
vec_any_nlt  
vec_any_numerics  
vec_any_out  
 
 

 

 

 


[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

Visit the Metrowerks website at: http://www.metrowerks.com
For assistance contact Metrowerks Technical Support at: cw_support@metrowerks.com
Copyright © 2000, Metrowerks Corp. All rights reserved.

Last updated: July 21, 2000