######

#
Reference

The Reference section describes the MIPS EABI and VR4300-specific attributes of the main GNUPro tools.

- Compiler
- EABI Summary
- Assembler
- Linker
- Debugger

## Compiler

This section describes VR4300-specific features of the GNUPro Compiler.

### VR4300-specific command-line options

For a list of available generic compiler options, refer to "GNU CC Command Options" in Using GNU CC in GNUPro Compiler Tools. In addition, the following VR4300-specific command-line options are supported:
`-EL`

Compile code for the processor in little endian mode.

`-EB`
Compile code for the processor in big-endian mode.

### Preprocessor symbols

Symbol | Compiler Options which define the Symbol
`mips` | only if '`-ansi`' not used
`_mips` | only if '`-ansi`' not used
`__mips` | always defined
`MIPSEB` | only if '`-ansi`' and '`-EL`' are not used
`_MIPSEB` | only if '`-EL`' is not used
`__MIPSEB` | only if '`-EL`' is not used
`__MIPSEB__` | only if '`-EL`' is not used
`R4300` | only if '`-ansi`' not used
`_R4300` | always defined
`MIPSEL` | only if '`-ansi`' is not used and '`-EL`' is used
`_MIPSEL` | only if '`-EL`' is used
`__MIPSEL` | only if '`-EL`' is used
`__MIPSEL__` | only if '`-EL`' is used

#### Note:

If neither '`-EL`' or '`-EB`' are defined big-endian is the default.

### VR4300-specific attributes

There are no VR4300-specific attributes. See "Declaring Attributes of Functions" and "Specifying Attributes of Variables" in "Extensions to the C Language Family" in Using GNU CC in GNUPro Compiler Tools for more information.

## New compiler and linker features

The GNUPro compiler and linker have been improved by Cygnus to provide even more benefits for customers developing for embedded targets. These features are guaranteed order of initialization at startup, and selective linking.

### Initialization prioritization

In C++, you can define static and global objects with constructors, or initialize static and global variables from a function. This means that the constructors or functions are run before the rest of your program starts. However, when you have these objects spread over multiple files, the C++ standard does not specify the order in which they are initialized, and for all practical purposes the order is random. For an embedded system, this can be a problem, as you may want to ensure that a static scheduler object is initialized before static threads can attach to it, or that devices are initialized before they are used. GNUPro solves this problem by allowing you to define a priority when the static or global is declared. The following example shows the syntax:

>     static object_t myobj __attribute__((init_priority (30000) ));

The syntax is slightly different if the object takes any arguments to its constructor:

>     static object_t myobj __attribute__((init_priority (30000) )) = \
>          object_t(arg1, arg2);

The numeric priority can be from 1 to 65535, with 1 being the highest priority, and 65535 being the lowest. The default priority for objects without this attribute is 65535. Constructors with a higher priority are guaranteed execution before constructors with lower priority.
In all cases, you must provide the argument '`-finit-priority`' to the compiler on its command-line for it to recognize this attribute when you are compiling your C++ source files.
If you are using eCos, be warned that eCos uses initialization priorities internally. Ensure you choose an appropriate priority level so that other eCos subsystems will have initialized before you refer to them in your own constructor.

### Selective linking

When writing C and C++ code, it is sometimes natural to include more than one function in a source file. For example in C++, it is common to have all methods for a particular class contained in the same C++ source file. However, there is a drawback that, conventionally, if you use just one of these functions, then all the functions defined in that file also get included in the final executable image. For an embedded system, this can substantially and unnecessarily increase the size of the final image stored in ROM, or loaded into RAM when debugging.
The GNUPro C and C++ compilers can now optionally remove these unnecessary functions from the final image. They also ensure that any shared global data is removed that is only referenced by functions that are removed. This can be done by including the options
`'-ffunction-sections`' and '`-fdata-sections`' on the command-line, when you invoke the C or C++ compiler.
The '`-ffunction-sections` ' option removes unnecessary functions, and the '`-fdata-sections`' option removes unnecessary data.
In addition, when classes define virtual methods in C++, it is possible to remove any unused methods from the final image by passing the option '`-fvtable-gc`' to the C++ compiler on its command-line.
In all cases, you must also supply a command-line option when linking. If invoking the linker ld directly, use '`--gc-sections`' on its command-line; alternatively, if you are using the preferred method of linking your executable, using the form '`gcc -o` <program name> <file1>.o <file2>`.o`', then also pass the option '`-Wl,- -gc-sections`' on the compiler command-line, for example:

>     gcc -o prog f1.o f2.o -Wl,--gc-sections

## EABI Summary

This section describes the MIPS EABI, which the VR4300 tools adhere to, by default.

### Data type sizes and alignments

The following table shows the size and alignment for all data types:

Type | Size (bytes) | Alignment (bytes)
`char` | 1 byte | 1 byte
`short` | 2 bytes | 2 bytes
`int` | 4 bytes | 4 bytes
`unsigned` | 4 bytes | 4 bytes
`long` | 4 bytes | 4 bytes
`long long` | 8 bytes | 8 bytes
`float` | 4 bytes | 4 bytes
`double` | 8 bytes | 8 bytes
pointer | 4 bytes | 4 bytes

- Alignment within aggregates (structs and unions) is as above, with padding added if needed
- Aggregates have alignment equal to that of their most aligned member
- Aggregates have sizes which are a multiple of their alignment

### Subroutine calls

The following describes the calling conventions for subroutine calls. The first table outlines the registers used for passing parameters. The second table outlines other register usage.

Parameter registers:
general-purpose | `r4-r11`
floating point | `f12-f19`

Register usage:
fixed 0 value | `r0`
volatile | `r1-r15, r24, r25`
non-volatile | `r16-r23, r30`
kernel reserved | `r26, r27`
gp (SDA base) | `r28`
stack pointer | `r28`
frame pointer | `r30` (if needed)
return address | `r33`

- General-purpose and floating-point parameter registers are allocated independently.
- Structures that are less than or equal to 32 bits are passed as values.
- Structures that are greater than 32 bits are passed as pointers.

### The Stack Frame

This section describes VR4300 stack frame:

- The stack grows downwards from high addresses to low addresses.
- A leaf function need not allocate a stack frame if it does not need one.
- A frame pointer need not be allocated.
- The stack pointer shall always be aligned to 8-byte boundaries.

Stack frames for functions that take a fixed number of arguments look like this:

#### *

If no '`alloca` ' region, the frame pointer (FP) points to the same location as SP.
Stack frames for functions that take a variable number of arguments look very similar, with the addition of an area on the stack that contains the arguments that were passed in registers.
Stack frames for functions that take a variable number of arguments look like this:

#### *

If no '`alloca` ' region, the frame pointer (FP) points to the same location as SP.

### Parameter Assignment to Registers

Consider the parameters in a function call as ordered from left (first parameter) to right. In this algorithm, 'FR' contains the number of the next available floating-point register (or register pair for modes in which floating-point registers hold only 32 bits). 'GR' contains the number of the next available general-purpose register. 'STARG' is the address of the next available stack parameter word.

#### INITIALIZE:

Set 'GR=r4', 'FR=f12', and 'STARG' to point to parameter word 1.

#### SCAN:

If there are no more parameters, terminate. Otherwise, select one of the following depending on the type of the next parameter:

#### DOUBLE OR FLOAT:

If 'FR > f19', go to 'STACK'. Otherwise, load the parameter value into
floating-point register 'FR' and advance 'FR' to the next floating-point register (or register pair in 32-bit mode). Then go to 'SCAN'.

#### SIMPLE ARG:

A SIMPLE ARG is one of the following:

- One of the simple integer types which will fit into a general-purpose register
- A pointer to an object of any type
- A struct or union small enough to fit in a register
- A larger struct or union, which shall be treated as a pointer to the object or to a copy of the object (See below for when copies are made.)

If 'GR > r11', go to 'STACK'. Otherwise, load the parameter value into general-purpose register 'GR' and advance 'GR' to the next general-purpose register. Values shorter than the register size are sign-extended or zero-extended depending on whether they are signed or unsigned. Then go to 'SCAN'.

#### LONG LONG in 32-bit mode:

If 'GR > r10', go to 'STACK'. Otherwise, if 'GR' is odd, advance 'GR' to the next register. Load the 64-bit '`long long`' value into register pair 'GR' and 'GR+1'. Advance 'GR' to 'GR+2' and go to 'SCAN'.

#### STACK:

Parameters not otherwise handled above are passed in the parameter words of the caller's stack frame. SIMPLE ARGs, as defined above, are considered to have size and alignment equal to the size of a general-purpose register, with simple argument types shorter than this sign- or zero-extended to this width. float arguments are considered to have size and alignment equal to the size of a floating-point register. In 64-bit mode, floats are stored in the low-order 32 bits of the 64-bit space allocated to them. '`double`' and '`long long`' are considered to have 64-bit size and alignment. Round 'STARG' up to a multiple of the alignment requirement of the parameter and copy the argument byte-for-byte into 'STARG', 'STARG+1', ... 'STARG+size-1'. Set 'STARG' to 'STARG+size' and go to 'SCAN'.

#### Structure passing

As noted above, code, which passes structures and unions by value is implemented specially. (In this section, "struct" will refer to structs and unions inclusively.) Structs small enough to fit in a register are passed by value in a single register or in a stack frame slot the size of a register. Larger structs are handled by passing the address of the structure. In this case, a copy of the structure will be made if necessary in order to preserve the pass-by-value semantics.
Copies of large structs are made under the following rules:

| ANSI mode | K&R Mode
Normal param | Callee copies if needed | Caller copies
Varargs (...) param | Caller copies | Caller copies

In the case of normal (non-varargs) large-struct parameters in ANSI mode, the callee is responsible for producing the same effect as if a copy of the structure were passed, preserving the pass-by-value semantics. This may be accomplished by having the callee make a copy, but in some cases the callee may be able to determine that a copy is not necessary in order to produce the same results. In such cases, the callee may choose to avoid making a copy of the parameter.

#### Varargs handling

No special changes are needed for handling varargs parameters other than the caller knowing that a copy is needed on struct parameters larger than a register (see above).
The varargs macros set up a two-part register save area, one part for the general-purpose registers and one part for floating-point registers, and maintain separate pointers for these two areas and for the stack parameter area. The register save area lies between the caller and callee stack frame areas.
In the case of software floating-point only the general-purpose registers need to be saved. Because the save area lies between the two stack frames, the saved register parameters are contiguous with parameters passed on the stack. This allows the varargs macros to be much simpler. Only one pointer is needed, which advances from the register save area into the caller's stack frame.

#### Function Return Values

Data types and register usage for return values:

Type | Register
`int` | `r2`
`short` | `r2`
`long` | `r2`
`long long` | `r2-r3` (32-bit mode)
`float` | `f0`
`double` | `f0-f1` (32-bit mode)
`struct/union` | see below

Structures and unions, which will fit into two general-purpose registers are returned in '`r2`', or in '`r2`' and '`r3`' if necessary. They are aligned within the register according to the endianness of the processor; in other words, on a big-endian processor the first byte of the struct is returned in the most significant byte of '`r2`', while on a little-endian processor the first byte is returned in the least significant byte of '`r2`'. The caller handles larger structures and unions, by passing, as a "hidden" first argument, a pointer to space allocated to receive the return value.

## Assembler

This section describes VR4300-specific features of the GNUPro Assembler.

### VR4300-specific command-line options

For a list of available generic assembler options, refer to "Command-Line Options" in Using AS in GNUPro Utilities .
`-EB`
`-EL`

Any MIPS configuration of the assembler can select big-endian or little-endian output at run time.

Use '`-EB`' to select big-endian output, and '`-EL`' for little-endian. The default is big-endian.

### Syntax

For information about the MIPS instruction set, see MIPS RISC Architecture , (Kane and Heindrich, Prentice-Hall). For an overview of MIPS assembly conventions, see "Appendix D: Assembly Language Programming" in the same volume.

### Register names

There are 32 64-bit general (integer) registers, named '`$0`' through '`$31`'. There are 32 64-bit floating-point registers, named '`$f0`'
through '`$f31`'.
The symbols '`$0`' through '`$31`' refer to the general-purpose registers.
The following symbols can be used as aliases for individual registers:

Symbol | Register
`$at` | `$1`
`$kt0` | `$26`
`$kt1` | `$27`
`$gp` | `$28`
`$sp` | `$29`
`$fp` | `$30`

### Assembler directives

This is a complete list of the VR4300 assembler directives.

`.abicalls` | `.dcb.b` | `.fail` | `.irepc` | `.psize`
`.abort` | `.dcb.d` | `.file` | `.irp` | `.purgem`
`.aent` | `.dcb.l` | `.fill` | `.irpc` | `.quad`
`.align` | `.dcb.s` | `.float` | `.lcomm` | `.rdata`
`.appfile` | `.dcb.w` | `.fmask` | `.lflags` | `.rep`
`.appline` | `.dcb.x` | `.format` | `.linkonce` | `.rept`
`.ascii` | `.debug` | `.frame` | `.list` | `.rva`
`.asciiz` | `.double` | `.global` | `.livereg` | `.sbttl`
`.asciz` | `.ds` | `.globl` | `.llen` | `.sdata`
`.balign` | `.ds.b` | `.gpword` | `.loc` | `.set`
`.balignl` | `.ds.d` | `.half` | `.long` | `.short`
`.balignw` | `.ds.l` | `.hword` | `.lsym` | `.single`
`.bgnb` | `.ds.p` | `.if` | `.macro` | `.skip`
`.bss` | `.ds.s` | `.ifc` | `.mask` | `.space`
`.byte` | `.ds.w` | `.ifdef` | `.mexit` | `.spc`
`.comm` | `.ds.x` | `.ifeq` | `.mri` | `.stabd`
`.common` | `.dword` | `.ifeqs` | `.name` | `.stabn`
`.common.s` | `.eject` | `.ifge` | `.noformat` | `.stabs`
`.cpadd` | `.else` | `.ifgt` | `.nolist` | `.string`
`.cpload` | `.elsec` | `.ifle` | `.nopage` | `.struct`
`.cprestore` | `.end` | `.iflt` | `.octa` | `.text`
`.data` | `.endb` | `.ifnc` | `.offset` | `.title`
`.dc` | `.endc` | `.ifndef` | `.option` | `.ttl`
`.dc.b` | `.endif` | `.ifne` | `.org` | `.verstamp`
`.dc.d` | `.ent` | `.ifnes` | `.p2align` | `.word`
`.dc.l` | `.equ` | `.ifnotdef` | `.p2alignl` | `.xcom`
`.dc.s` | `.equiv` | `.include` | `.p2alignw` | `.xdef`
`.dc.w` | `.err` | `.insn` | `.page` | `.xref`
`.dc.x` | `.exitm` | `.int` | `.plen` | `.xstabs`
`.dcb` | `.extern` | `.irep` | `.print` | `.zero`

### MIPS Synthetic Instructions Supported for the VR4300

The VR4300 GAS assembler supports the typical MIPS synthetic instructions (macros). What follows is a list of synthetic instructions supported by the assembler, as well as an example expansion of each instruction.
R1 R2 R3 - Integer registers
F1 F2 F3 - Floating point registers
I1 I2 I3 - Immediate integer values

Instruction | Expansion
--- | ---
`abs R1 R2` | `bgez R2,abs_1` `move R1,R2` `neg R1,R2` `abs_1:`
`add R1 R2 I1` | `addi R1,R2,I1`
`addu R1 R2 I1` | `addiu R1,R2,I1`
`and R1 R2 I1` | `andi R1,R2,I1`
`beq R1 I1 I2` | `li $at,I1` `beq R1,$at,+I2`
`beql R1 I1 I2` | `li $at,I1` `beql R1,$at,+I2`
`bge R1 R2 I1` | `slt $at,R1,R2` `beqz $at,+I1`
`bge R1 I1 I2` | `slti $at,R1,I1` `beqz $at,+I2`
`bgel R1 R2 I1` | `slt $at,R1,R2` `beqzl $at,+I1`
`bgel R1 I1 I2` | `slti $at,R1,I1` `beqzl $at,+I2`
`bgeu R1 R2 I1` | `sltu $at,R1,R2` `beqz $at,+I1`
`bgeu R1 I1 I2` | `sltiu $at,R1,I1` `beqz $at,+I2`
`bgeul R1 R2 I1` | `sltu $at,R1,R2` `beqzl $at,+I2`
`bgeul R1 I1 I2` | `sltiu $at,R1,I1 beqzl $at,+I2`
`bgt R1 R2 I1` | `slt $at,R2,R1` `bnez $at,+I1`
`bgt R1 I1 I2` | `slti $at,R1,I1+1` `beqz $at,+I2`
`bgtl R1 R2 I1` | `slt $at,R2,R1` `bnezl $at,+I1`
`bgtl R1 I1 I2` | `slti $at,R1,I1+1` `beqzl $at,+I2`
`bgtu R1 R2 I1` | `sltu $at,R2,R1` `bnez $at,+I2`
`bgtu R1 I1 I2` | `sltiu $at,R1,I2+1` `beqz $at,+I2`
`bgtul R1 R2 I1` | `sltu $at,R2,R1` `bnezl $at,+I1`
`bgtul R1 I1 I2` | `sltiu $at,R1,I1+1` `beqzl $at,+I2`
`ble R1 R2 I1` | `slt $at,R2,R1` `beqz $at,+I1`
`ble R1 I1 I2` | `slti $at,R1,I1+1` `bnez $at,+I2`
`blel R1 R2 I1` | `slt $at,R2,R1` `beqzl $at +I2`
`blel R1 I1 I2` | `slti $at,R1,I1+1` `bnezl $at,+I2`
`bleu R1 R2 I1` | `sltu $at,R2,R1` `beqz $at,+I1`
`bleu R1 I1 I2` | `sltiu $at,R1,I1+1` `bnez $at,+I2`
`bleul R1 R2 I1` | `sltu $at,R2,R1` `beqzl $at,+I1`
`bleul R1 I1 I2` | `sltiu $at,R1,I1+1` `bnezl $at,+I2`
`blt R1 R2 I1` | `slt $at,R1,R2` `bnez $at,+I1`
`blt R1 I1 I2` | `slti $at,R1,I1` `bnez $at,+I2`
`bltl R1 R2 I1` | `slt $at,R1,R2` `bnezl $at,+I1`
`bltl R1 I1 I2` | `slti $at,R1,I1` `bnezl $at,+I2`
`bltu R1 R2 I1` | `sltu $at,R1,R2` `bnez $at,+I1`
`bltu R1 I1 I2` | `sltiu $at,R1,I1` `bnez $at,+I2`
`bltul R1 R2 I1` | `sltu $at,R1,R2` `bnezl $at,+I1`
`bltul R1 I1 I2` | `sltiu $at,R1,I1` `bnezl $at,+I2`
`bne R1 I1 I2` | `li $at,I1` `bne R1,$at,+I2`
`bnel R1 I1 I2` | `li $at,I1` `bnel R1,$at,+I2`
`dabs R1 R2` | `bgez R2,dabs_1` `move R1,R2` `dneg R1,R2` `dabs_1:`
`dadd R1 R2 I1` | `daddi R1,R2,I1`
`daddu R1 R2 I1` | `daddiu R1,R2,I1`
`ddiv R1 R2 R3` | `bnez R3,L1_ddiv` `ddiv $zero,R2,R3` `break 0x7` `ddiv_1:` `daddiu $at,$zero,-1` `bne R3,$at,ddiv_2` `daddiu $at,$zero,1` `dsll32 $at,$at,0x1f` `bne R2,$at,ddiv_2` `nop` `break 0x6` `ddiv_2:` `mflo R1`
`ddiv R1 R2 I1` | `li $at,I1` `ddiv $zero,R2,$at` `mflo R1`
`ddivu R1 R2 R3` | `bnez R3,ddivu_1` `ddivu $zero,R2,R3` `break 0x7` ddivu_1: `mflo R1`
`ddivu R1 R2 I1` | `li $at,I1` `ddivu $zero,R2,$at` `mflo R1`
`div R1 R2 R3` | `bnez R3,div_1` `div $zero,R2,R3` `break 0x7` `div_1:` `li $at,-1` `bne R3,$at,div_2` `lui $at,0x8000` `bne R2,$at,div_2` `nop` `break 0x6` `div_2:` `mflo R1`
`div R1 R2 I1` | `li $at,I1` `div $zero,R2,$at` `mflo R1`
`divu R1 R2 R3` | `bnez R3,divu_1` `divu $zero,R2,R3` `break 0x7` `divu_1:` `mflo R1`
`divu R1 R2 I1` | `li $at,I1` `divu $zero,R2,$at` `mflo R1`
`dla R1 I1(R2)` | `li R1,I1` `addu R1,R1,R2`
`dli R1 I1` | `li R1,I1`
`drem R1 R2 R3` | `bnez R3,drem_1` `ddiv $zero,R2,R3` `break 0x7` `drem_1:` `daddiu $at,$zero,-1` `bne R3,$at,drem_2` `daddiu $at,$zero,1` `dsll32 $at,$at,0x1f` `bne R2,$at,drem_2` `nop` `break 0x6` `drem_2:` `mfhi R1`
`drem R1 R2 I1` | `li $at,I1` `ddiv $zero,R2,$at` `mfhi R1`
`dremu R1 R2 R3` | `bnez R3,dremu_1` `ddivu $zero,R2,R3` `break 0x7` `dremu_1:` `mfhi R1`
`dremu R1 R2 I1` | `li $at,I1` `ddivu $zero,R2,$at` `mfhi R1`
`dsub R1 R2 I1` | `daddi R1,R2,-I1`
`dsubu R1 R2 I1` | `daddiu R1,R2,-I1`
`flush R1 I1(R2)` | `lwr R1,I1(R2)`
`jal R1 R2` | `jalr R1,R2`
`jal R1` | `jalr R1`
`la R1 I1(R2)` | `li R1,I1` `addu R1,R1,R2`
`l.d F1 I1(R1)` | `ldc1 F1,I1(R1)`
`ldc3 R1 I1(R2)` | `ld R1,I1(R2)`
`li.d R1 I1` | `li R1,0x8066` `dsll32 R1,R1,0xf`
`li.d F1 I1` | `li $at,0x8066` `ds1132 $at,$at,0xf` `dmtc1 $at,F1`
`li.s R1 I1` | `lui R1,0x4198`
`li.s F1 I1` | `lui $at,0x4198` `mtc1 $at,F1`
`lwc0 R1 I1(R2)` | `ll R1,I1(R2)`
`l.s F1 I1(R1)` | `lwc1 F1,I1(R1)`
`lcache R1 I1(R2)` | `lwl R1,I1(R2)`
`nor R1 R2 I1` | `ori R1,R2,I1` `nor R1,R1,$zero`
`or R1 R2 I1` | `ori R1,R2,I1`
`rem R1 R2 R3` | `bnez R3,rem_1` `div $zero,R2,R3` `break 0x7` `rem_1:` `li $at,-1` `bne R3,$at,rem_2` `lui $at,0x8000` `bne R2,$at,rem_2` `nop` `break 0x6` `rem_2:` `mfhi R1`
`rem R1 R2 I1` | `li $at,I1` `div $zero,R2,$at` `mfhi R1`
`remu R1 R2 R3` | `bnez R3,remu_1` `divu $zero,R2,R3` `break 0x7` `remu_1:` `mfhi R1`
`remu R1 R2 I1` | `li $at,I1` `divu $zero,R2,$at` `mfhi R1`
`rol R1 R2 R3` | `negu $at,R3` `srlv $at,R2,$at` `sllv R1,R2,R3` `or R1,R1,$at`
`rol R1 R2 I1` | `sll $at,R2,I1` `srl R1,R2,32-I1` `or R1,R1,$at`
`ror R1 R2 R3` | `negu $at,R3` `sllv $at,R2,$at` `srlv R1,R2,R3` `or R1,R1,$at`
`ror R1 R2 I1` | `srl $at,R2,I1` `sll R1,R2,32-I1` `or R1,R1,$at`
`sdc3 R1 I1(R2)` | `sd R1,I1(R2)`
`s.d F1 I1(R1)` | `sdc1 F1,I1(R1)`
`seq R1 R2 R3` | `xor R1,R2,R3` `sltiu R1,R1,1`
`seq R1 R2 I1` | `xori R1,R2,I1` `sltiu R1,R1,1`
`sge R1 R2 R3` | `slt R1,R2,R3` `xori R1,R1,0x1`
`sge R1 R2 I1` | `slti R1,R2,I1` `xori R1,R1,0x1`
`sgeu R1 R2 R3` | `sltu R1,R2,R3` `xori R1,R1,0x1`
`sgeu R1 R2 I1` | `sltiu R1,R2,I1` `xori R1,R1,0x1`
`sgt R1 R2 R3` | `slt R1,R3,R2`
`sgt R1 R2 I1` | `li $at,I1` `slt R1,$at,R2`
`sgtu R1 R2 R3` | `sltu R1,R3,R2`
`sgtu R1 R2 I1` | `li $at,I1` `sltu R1,$at,R2`
`sle R1 R2 R3` | `slt R1,R3,R2` `xori R1,R1,0x1`
`sle R1 R2 I1` | `li $at,I1` `slt R1,$at,R2` `xori R1,R1,0x1`
`sleu R1 R2 R3` | `sltu R1,R3,R2` `xori R1,R1,0x1`
`sleu R1 R2 I1` | `li $at,I1` `sltu R1,$at,R2` `xori R1,R1,0x1`
`slt R1 R2 I1` | `slti R1,R2,I1`
`sltu R1 R2 I1` | `sltiu R1,R2,I1`
`sne R1 R2 R3` | `xor R1,R2,R3` `sltu R1,$zero,R1`
`sne R1 R2 I1` | `xori R1,R2,I1` `sltu R1,$zero,R1`
`sub R1 R2 I1` | `addi R1,R2,-I1`
`subu R1 R2 I1` | `addiu R1,R2,-I1`
`swc0 R1 I1(R2)` | `sc R1,I1(R2)`
`s.s F1 I1(R1)` | `swc1 F1,I1(R1)`
`scache R1 I1(R2)` | `swl R1,I1(R2)`
`invalidate R1 I1(R2)` | `swr R1,I1(R2)`
`teq R1 I1` | `teqi R1,I1`
`tge R1 I1` | `tgei R1,I1`
`tgeu R1 I1` | `tgeiu R1,I1`
`tlt R1 I1` | `tlti R1,I1`
`tltu R1 I1` | `tltiu R1,I1`
`tne R1 I1` | `tnei R1,I1`
`trunc.w.d F1 F2 R1` | `trunc.w.d F1,F2`
`trunc.w.s F1 F2 R1` | `trunc.w.s F1,F2`
`uld R1 I1(R2)` | `ldl R1,I1(R2)` `ldr R1,I1(R2)`
`ulh R1 I1(R2)` | `lb R1,I1(R2)` `lbu $at,I1(R2)` `sll R1,R1,0x8` `or R1,R1,$at`
`ulhu R1 I1(R2)` | `lbu R1,I1(R2)` `lbu $at,I1(R2)` `sll R1,R1,0x8` `or R1,R1,$at`
`ulw R1 I1(R2)` | `lwl R1,I1(R2)` `lwr R1,I1(R2)`
`usd R1 I1(R2)` | `sdl R1,I1(R2)` `sdr R1,I1(R2)`
`ush R1 I1(R2)` | `sb R1,I1(R2)` `srl $at,R1,0x8` `sb $at,I1(R2)`
`usw R1 I1(R2)` | `swl R1,I1(R2)` `swr R1,I1(R2)`
`xor R1 R2 I1` | `xori R1,R2,I1`

## Linker

eCos generates linker scripts appropriate for the exact eCos configuration you have chosen. Instructions on how to use this linker script are provided in the manual Getting Started with eCos .

### VR4300-specific command-line options

For a list of available generic linker options, refer to "Linker scripts" in Using LD in GNUPro Utilities . There are no VR4300-specific command-line linker options.

## Debugger

The following instructions connect GDB to the remote target board. To load your program onto the standard evaluation board, build eCos for the hardware with RAM startup. Provided the board is fitted with CygMon ROMs, or GDB loader stub ROMs, you may connect to the target board in GDB using the command '`target remote`<devicename>' where '<devicename>' will be a serial device such as '`com2`' (Windows NT) or '`/dev/ttyS1`' (Linux). Then load the code onto the target board by typing '`load`'. After being downloaded, the program can be executed.

#### Note:

When using the remote target, GDB does not accept the '`run`' command. However, since downloading the program has the side effect of setting the PC to the start address, you can start your program by typing '`continue`' (the letter '`c`' works as a shortcut for the '`continue`' command).

### VR4300-specific command-line options

For the available generic debugger options, refer to Debugging with GDB in GNUPro Debugging Tools . There are no VR4300-specific debugger command-line options.

### Debugging programs with multiple threads

Programs with multiple threads can be debugged using either the graphic user interface to GDB, GDBTk or the GDB command line interface. The following describes how to debug multiple threads using the GDB command line.
In some operating systems, such as eCos, a single program may have more than one thread of execution. The precise semantics of threads differ from one operating system to another, but in general the threads of a single program are akin to multiple processes, except that they share one address space (that is, they can all examine and modify the same variables). On the other hand, each thread has its own registers and execution stack, and perhaps private memory.
GDB provides the following functions for debugging multi-thread programs

- `'info threads`', a command to inquire about existing threads
- `'thread` <threadno>', a command to switch among threads
- `'thread apply [`<threadno>`][`<all>`]` <args>', a command to apply a command to a list of threads
- thread-specific breakpoints

The GDB thread-debugging facility allows you to observe all threads while your program runs, but whenever GDB takes control, one thread in particular is always the focus of debugging. This thread is called the current thread. Debugging commands show program information from the perspective of the current thread.
For debugging purposes, GDB associates its own thread number, always a single integer, with each thread in your program.
`info threads`

Display a summary of all threads currently in your program. GDB displays for each thread (in the following order):

1. The thread number assigned by GDB
2. The target system's thread ID
3. The current stack frame summary for that thread

An asterisk '`*`' to the left of the GDB thread number indicates the current thread. Use the following example for clarity.

    (gdb)
         info threads
       * 2 thread 2  breakme ()
        at /eCos/packages/kernel/v1_2_2/tests/thread_gdb.c:91
        Name: controller, State: running, Priority: 0, More: <none>
        1 thread 1  Cyg_HardwareThread::thread_entry (thread=0x1111aaa2)
        at /eCos/packages/kernel/v1_2_2/src/common/thread.cxx:68
        Name: Idle Thread, State: running, Priority: 31, More: <none>

`thread` <threadno>
Make thread number '<threadno>' the current thread. The command argument, '<threadno>', is the internal GDB thread number, as shown in the first field of the 'info threads' display. GDB responds by displaying the system identifier of the thread you selected, and its current stack frame summary, as in the following output.

    (gdb)
          thread 2
        [Switching to thread 2]
        #0  change_state (id=0, newstate=0 '\000')
        at /eCos/kernel/current/tests/bin_sem2.cxx:93
        93          if (PHILO_LOOPS == state_changes++)
        Current language:  auto; currently c++

`thread apply [`<threadno>`][`<all>`]` <args>
The thread apply command allows you to apply a command to one or more threads. Specify the numbers of the threads that you want affected with the command argument '<threadno>', where '<threadno>' is the internal GDB thread number, as shown in the first field of the '`info threads`' display. To apply a command to all threads, use '`thread apply all args` '.

Whenever GDB stops your program, due to a breakpoint or a signal, it automatically selects the thread where that breakpoint or signal happened.

When your program has multiple threads, you can choose whether to set breakpoints on all threads, or on a particular thread.

>     break <linespec> thread <threadno>

If '<linespec>' specifies source lines, then there are several ways of writing them. Use the qualifier '`thread` <threadno>' with a breakpoint command to specify that you only want GDB to stop the program when a particular thread reaches this breakpoint. '<threadno>' is one of the numeric thread identifiers assigned by GDB, shown in the first column of the 'info threads' display.
If you do not specify '`thread` <threadno>' when you set a breakpoint, the breakpoint applies to all threads of your program.
You can use the thread qualifier on conditional breakpoints as well; in this case, place '`thread` <threadno> ' before the breakpoint condition, as the following example shows.

> >     (gdb) break frik.c:(13 thread 28 if bartab > lim

Whenever your program stops under GDB for any reason, all threads of execution stop; not just the current thread. This allows you to examine the overall state of the program, including switching between threads, without worrying that things may change.
Conversely, whenever you restart the program, all threads start executing. This is true even when single stepping with commands like '`step` ' or '`next`'. In particular, GDB cannot single-step all threads in lockstep. Since thread scheduling is up to your debugging target's operating system (not controlled by GDB), other threads may execute more than one statement while the current thread completes a single step. In general other threads stop in the middle of a statement, rather than at a clean statement boundary, when the program stops.
You might even find your program stopped in another thread after continuing or even single stepping. This happens whenever some other thread runs into a breakpoint, a signal, or an exception before the first thread completes whatever you requested.

#### SET SCHEDULER-LOCKING

For targets that support it, GDB has a new command that helps to debug multi-threaded programs. The '`set scheduler-locking [on off step]`' command allows the GDB user to exert some control over how threads are scheduled while debugging.
Normally GDB does not attempt to interfere with thread scheduling. This means that in the default mode ('`scheduler-locking off`'), the current thread may be scheduled out, and a different thread may begin running, at any time (as determined by the native scheduler). For instance, you may give a GDB command such as '`step`' or '`finish`', and when the command completes, you may be looking at a different thread.
If you set the scheduler-locking mode to '`step`', then GDB will try to interfere with the native scheduler just enough to prevent another thread from popping up while you debug. Other threads may get to run sometimes, but whenever a command such as '`step`' or '`finish`' completes, you should be looking at the same thread that was running before the command. Of course, if another thread gets to run and hits a breakpoint, GDB will still switch you to that thread (so if you don't want that to happen, then disable your breakpoints).
For even greater (and more intrusive) control over the thread scheduler, GDB provides the mode '`scheduler-locking on`'. In this mode, the native scheduler is completely locked, and no thread may run except the current one. Obviously this will radically change the behavior of your program, and may lead to deadlock or other unpleasant consequences, so use it with caution.

#### Syntax:

> `set scheduler-locking [off on step]`

> Set mode for locking scheduler during target execution.

> `off`
> No locking (threads may preempt at any time).

> `on`

> Full locking (no thread except the current thread may run).

> `step`

The scheduler is locked during every single-step operation. In this mode, no other thread may run during a step command. However, other threads may run while stepping over a function call ('`next`').