The
following documentation describes information pertinent only to LSI TinyRISC
processors using GNUPro Toolkit software.
Compiler
features for LSI TinyRISC
The following
features for the GNUPro compiler have support for the LSI TinyRISC processor.
The following
MIPS16-specific command-line options are supported. For a list of all the
available generic compiler options, see GNU
CC command options in Using
GNU CC in GNUPro Compiler Tools.
Compile code for the processor in mips16 mode.
The -mentry option tells the compiler
to use the entry and exit pseudo-instructions for function entry and exit.
The pseudo-instructions save and restore registers at function entry and
exit. These work by triggering an unimplemented instruction trap. Your
exception handler must handle these instructions correctly. This is a time/space
tradeoff; code using the entry and exit instructions is smaller, but takes
longer to execute.
Any MIPS configuration of the compiler can select
big-endian or little-endian output at run time. Use -EB to select
big-endian output and -EL for little-endian. If neither -EL
nor -EB are defined, big-endian is the default.
See Preprocessor
symbols for the preprocessor symbols and the compiler options that
define them.
|
Compiler
options that define symbol
|
|
|
|
|
|
|
|
|
|
Only if
-ansi
and -EL are not used
|
|
|
|
|
|
|
|
Only if
-ansi
is not used and -EL is used
|
|
|
|
|
|
|
ABI summary
for LSI TinyRISC
T
he following
documentation details the Application Binary Interface (ABI) for the LSI
TinyRISC processor.
Data type sizes and alignments
for the LSI TinyRISC
The following
information defines the data type sizes and alignments. The stack is aligned
on eight-byte boundaries.
Register
allocation definitions for the LSI TinyRISC
Register
allocation definitions
General
purpose (integer) register
|
|
|
|
|
$1 through $15
, $24 , $25
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Do not depend
on the order of the registers shown in Register
allocation definitions. Instead, use GCC’s asm( ) extension
and allow the compiler to schedule registers.
Stack frame features for the
LSI TinyRISC
The following
specific issues for the stack frame have support for the LSI TinrRISC processor.
See also Stack frame for LSI TinyRISC
(below).
-
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.
Calling
conventions for LSI TinyRISC
The following
documentation defines the calling conventions
for the LSI TinyRISC processor.
Argument
passing for the LSI TinyRISC
When compiling
in mips16 mode, the floating point registers are not available. A function
compiled in mips16 mode expects floating point arguments in the general
registers, and it returns a floating point value in the general registers.
The compiler and the linker cooperate to make this happen transparently
when a function compiled in mips16 mode calls a function compiled in mips32
mode, or vice-versa. If you write your own assembly language code, and
plan to call between mips16 code and mips32 code, you must arrange for
the function arguments and return values to be in the right place for both
the caller and the callee.
On the mips16,
floating point values are returned as though they were integer values.
A single precision floating point value is returned in general register
` $2'. A double precision floating point value is returned in
general registers `$2' and `$3'.
The compiler
passes arguments to a function using a combination of integer general registers,
and the stack. The number, type, and relative position of arguments in
the calling functions argument list define the combination of registers
and memory used. The general registers `$4..$7' pass the first
few arguments.
If the function
being called returns a structure or union, the calling function passes
the address of an area large enough to hold the structure to the function
in `$4'. The function being called copies the returned structure
into this area before returning. The address in `$4' becomes the
first argument to the function for the purpose of argument register allocation.
All user arguments are then shifted down by one.
The compiler always
allocates space on the stack for all arguments even when some or all of
the arguments to a function are passed in registers. This stack space is
a large enough structure to contain all the arguments. After promotion
and structure return pointer insertion, the arguments are aligned according
to normal structure rules. Locations used for arguments within the stack
frame are referred to as the home locations. Whenever possible, arguments
declared in variable argument lists, as with those defined using a `va_list'
declaration, are passed in the integer registers, even when they are floating-point
numbers.
If the first argument
is an integer, remaining arguments are passed in the integer registers.
The compiler passes
structures and unions as if they were very wide integers with their size
rounded up to an integral number of words. The "fill bits" necessary for
rounding up are undefined. A structure can be split so that a portion is
passed in registers and the remainder passed on the stack. In this case,
the first words are passed in `$4', `$5', `$6',
and `$7' as needed, with additional words passed on the stack.
The rules for
assigning which arguments go into registers and which arguments must be
passed on the stack can be explained by considering the list of arguments
itself as a structure, aligned according to normal structure rules. Mapping
of this structure into the combination of registers and stack is as follows;
everything with a structure offset greater than or equal to 32 is passed
on the stack. The remainder of the arguments are passed in `$4..$7'
based on their structure offset. Any holes left in the structure for alignment
are unused, whether in registers or on the stack.
Function return values for
the LSI TinyRISC
A function can
return no value, an integral or pointer value, a floating-point value (single
or double precision), or a structure; unions are treated the same as structures.
A function that
returns no value puts no particular value in any register.
A function that
returns an integral or pointer value places its result in register `$2'.
A function that
returns a floating-point value places its result in general register `$2'.
The caller to
a function that returns a structure or a union passes the address of an
area large enough to hold the structure in register `$4'. The
function returns a pointer to the returned structure in register `$2'.
Assembler
features for the LSI TinyRISC
The following
documentation defines the specific assembler options for the LSI TinyRISC
processor. For a list of available generic assembler options, see Command-line
options in Using as in GNUPro Utilities.
Assemble code for the processor in mips16 mode.
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.
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.
There are 32 64-bit general
(integer) registers, named `$0..$31'. There are 32 64-bit floating
point registers, named `$f0..$f31'.
For assembler
mnemonics, see MIPS16 ASE Reference Manual.
Linker
features for the LSI TinyRISC
For a list of
available generic linker options, see Linker
scripts in Using ld in GNUPro Utilities.
In addition, the following MIPS-specific command-line options have support.
Link objects for the processor in little endian
mode.
Link objects for the processor in big-endian
mode.
Linker script for LSI TinyRISC
The GNU linker
uses a linker script to determine how to process each section in an object
file, and how to lay out the executable. The linker script is a declarative
program consisting of a number of directives. For instance, the directive
`ENTRY( )' specifies which symbol in the executable is designated
the executable’s entry point. Since linker scripts can be complicated
to write, the linker includes one built-in script that defines the default
linking process.
Use the following
linker script (`lsi.ld') when linking programs for the TinyRISC
board. Also, use it to link programs for execution in the MIPS simulator.
/* The following TEXT start address leaves space for the monitor
workspace. */
ENTRY(_start)
OUTPUT_ARCH("mips:4000")
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips")
GROUP(-lc -llsi -lgcc)
SEARCH_DIR(.)
__DYNAMIC = 0;
/*
* Allocate the stack to be at the top of memory, since the
* stack grows down
*/
PROVIDE (__stack = 0);
/* PROVIDE (__global = 0); */
/*
* Initalize some symbols to be zero so we can reference them
* in the crt0 without core dumping. These functions are all
* optional, but we do this so we can have our crt0 always use
* them if they exist. This is so BSPs work better when using
* the crt0 installed with gcc. We must initalize them twice,
* so we multiple object file formats, as some prepend an
* underscore. */
PROVIDE (hardware_init_hook = 0);
PROVIDE (software_init_hook = 0);
SECTIONS
{
. = 0xA0020000;
.text : {
_ftext = . ;
*(.init)
eprol = .;
*(.text)
PROVIDE (__runtime_reloc_start = .);
*(.rel.sdata)
PROVIDE (__runtime_reloc_stop = .);
*(.fini)
etext = .;
_etext = .;
}
. = .;
.rdata : {
*(.rdata)
}
_fdata = ALIGN(16);
.data : {
*(.data)
CONSTRUCTORS
}
. = ALIGN(8);
_gp = . + 0x8000;
__global = _gp;
.lit8 : {
*(.lit8)
}
.lit4 : {
*(.lit4)
}
.sdata : {
*(.sdata)
}
edata = .;
_edata = .;
_fbss = .;
.sbss : {
*(.sbss)
*(.scommon)
}
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
}
end = .;
_end = .;
}
Debugger
features for the LSI TinyRISC
GDB
uses the MIPS remote debugging protocol to talk to a target via a serial
port. To run a program on the TinyRISC board, start up GDB with the name
of your program as the argument to the GDB call: mips-lsi-elf-gdb<program>,
for example.
Use the `target
lsi <port>' command to specify the connection to
your target board, where `<port>'is the name of the
serial port connected to the board. If the program has not already been
downloaded to the board, use the `load' command to download it.
You can then use all the usual GDB commands. For example, the following
sequence connects to the target board through a Unix serial port, and loads
and runs a program called `prog' through the debugger.
mips-lsi-elf-gdb prog
GDB is free software and . . .
(gdb)target lsi /dev/ttyb
(gdb)load prog
(gdb)run
On PC platforms, substitute the specific COM port:
C:\> mips-lsi-elf-gdbprog
GDB is free software and . . .
(gdb)target lsi com3
(gdb)load prog
(gdb)run
Special commands for LSI
TinyRISC
GDB also supports
the following special commands for MIPS targets.
For this to be useful, you must know something
about the MIPS debugging protocol, also called `rmtdbg'. An informal
description can be found in the GDB source files, specifically in the `remote-mips.c'
file .
You
can see some debugging information about communications with the board
by setting the `remotedebug'variable. If you set it to 1 using
the `set remotedebug 1' command, every packet is displayed. If
you set it to 2, every character is displayed. You can check the current
value at any time with the `showremotedebug' command.
You can control the timeout used while waiting
for a packet, in the MIPS debugging protocol, with the `set timeout
seconds' command. The default is 5 seconds. Similarly, you can control
the timeout used while waiting for an acknowledgment of a packet with the
set
retransmit-timeout seconds command. The default is 3 seconds. You
can inspect both values with the `show timeout' and `show
retransmit-timeout' commands.
The
timeout set by `set timeout' does not apply when GDB is waiting
for your program to stop. In that case, GDB waits forever because it has
no way of knowing how long the program is going to run before stopping.
Stand-alone
simulator issues for LSI TinyRISC
Three run-time
command-line options are available with the stand-alone simulator: -t,
-v,
and -m, as the following documentation describes.
The `-t'
command-line option to the stand-alone simulator turns on tracing of all
memory fetching and storing in the simulator, as the following example
shows.
C:\>mips-lsi-elf-run -t hello.xb
C:\>
The simulator
writes the trace information to the file `trace.din'. The following
example shows the first few lines of a trace file.
2 a0020000 ; width 4 ; load instruction
2 a0020004 ; width 4 ; load instruction
2 a0020008 ; width 4 ; load instruction
2 a002000c ; width 4 ; load instruction
2 a0020010 ; width 4 ; load instruction
2 a0020014 ; width 4 ; load instruction
2 a0020018 ; width 4 ; load instruction
2 a002001c ; width 4 ; load instruction
2 a0020020 ; width 4 ; load instruction
2 a0020024 ; width 4 ; load instruction
. . .
The `-v'
command-line option prints some simple statistics, as the following example
shows.
%mips-lsi-elf-run -v hello.xb
mips-lsi-elf-run hello
Hello, world!
3 + 4 = 7
MIPS 32-bit simulator
Big endian memory model
0x00200000 bytes of memory at 0xa0000000
Instruction fetches = 4138
Pipeline ticks = 4138
The `-m'
command-line option sets the size of the simulated memory area. The default
size is 1048576 bytes (1 megabyte). The simulator rounds up the size you
request to the next power of two. See the following example script for
details.
%mips-lsi-elf-run -v -m 200000 hello.xb
mips-lsi-elf-run hello
Hello, world!
3 + 4 = 7
MIPS 32-bit simulator
Big endian memory model
0x00040000 bytes of memory at 0xa0000000
Instruction fetches = 4138
Pipeline ticks = 4138
Top|Contents|Index|Previous|Next