Skip to content

Commit

Permalink
release-v1.1 (#15)
Browse files Browse the repository at this point in the history
Signed-off-by: yaopengfei <[email protected]>
  • Loading branch information
ypf79 authored Nov 1, 2024
1 parent a48c794 commit 005a9cb
Show file tree
Hide file tree
Showing 56 changed files with 1,810 additions and 490 deletions.
19 changes: 17 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
SRC = la-asm-manual.adoc
PDF = la-asm-manual.pdf

PDF_THEME = themes/la-asm-manual-pdf.yml

.PHONY: all clean

$(PDF): $(PDF:.pdf=.adoc) $(SRC)
asciidoctorj -b pdf $(SRC) -o $(PDF)
$(PDF): $(PDF:.pdf=.adoc) $(SRC) $(PDF_THEME)
/usr/bin/asciidoctor-pdf \
-a compress \
-a date="$(DATE)" \
-a monthyear="$(MONTHYEAR)" \
-a pdf-style="$(PDF_THEME)" \
-a pdf-fontsdir=fonts \
-v \
la-asm-manual.adoc -o $@


html: $(patsubst %.adoc, %.html, $(SRC))

%.html: %.adoc
asciidoctor $^ -o $@

clean:
-rm -rf la-asm-manual.pdf
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This is the official documentation of the Assembly Language Programming Guide fo

## Releases

The latest Assembly Language Programming Guide documentation releases are available at https://github.com/loongson/la-asm-manual/releases and are licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License.
The latest Assembly Language Programming Guide documentation releases are available at https://github.com/loongson/la-asm-manual/releases and are licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) License.

## Defect reports

Expand All @@ -17,9 +17,9 @@ Please refer to the contribution guidelines in [CONTRIBUTING](CONTRIBUTING.md).

## License

The Assembly Language Programming Guide documents and their source files are currently licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License. Contributions to these files are accepted under the same license.
The Assembly Language Programming Guide documents and their source files are currently licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) License. Contributions to these files are accepted under the same license.

To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.

## Revision History

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
=== *1.1 `LoongArch` Architecture Overview*

[.text-justify]
*`LoongArch`* has the typical characteristics of RISC. *`LoongArch`* instructions are of fixed size and have regular instruction formats. Most of the instructions have two source operands and one destination operand. *`LoongArch`* is a load-store architecture; this means only the load/store instructions can access memory the operands of the other instructions are within the processor core or the immediate number in the instruction opcode.
*`LoongArch`* has the typical characteristics of RISC. Its instructions are of fixed size and follow regular formats. Most instructions use two source operands and one destination operand. *`LoongArch`* is a load-store architecture, meaning that only load and store instructions can access memory; the operands of other instructions reside within the processor core or are immediate values specified in the instruction opcode.

[.text-justify]
*`LoongArch`* is divided into two versions, the 32-bit version (*`LA32`*) and the 64-bit version (*`LA64`*). *`LA64`* applications are “application-level backward binary compatibility” with *`LA32`* applications. That means *`LA32`* applications can run directly on the machine compatible with *`LA64`*, but the behavior of system softwares (such as the kernel) on the machine compatible with *`LA32`* is not guaranteed to be the same as on the machine compatible with *`LA64`*.
*`LoongArch`* is divided into two versions: the 32-bit version (*`LA32`*) and the 64-bit version (*`LA64`*). *`LA64`* applications provide “application-level backward binary compatibility” with *`LA32`* applications, meaning that *`LA32`* applications can run directly on a machine compatible with *`LA64`*. However, the behavior of system software, such as the kernel, on a machine compatible with LA32 is not guaranteed to be the same as on a machine compatible with LA64.

[.text-justify]
*`LoongArch`* is composed of a basic part (*`Loongson Base`*) and an expanded part, as shown in the figure. The expansion part includes Loongson Binary Translation (*`LBT`*), Loongson VirtualiZation (*`LVZ`*), Loongson SIMD EXtension (*`LSX`*), and Loongson Advanced SIMD EXtension(*`LASX`*).
*`LoongArch`* is composed of a basic part (*`Loongson Base`*) and an expanded part, as shown in the figure. The expansion part includes Loongson Binary Translation (*`LBT`*), Loongson Virtualization (*`LVZ`*), Loongson SIMD Extension (*`LSX`*), and Loongson Advanced SIMD Extension(*`LASX`*).
2 changes: 1 addition & 1 deletion adoc/CHAPTER-1.Introduction/1.Introduction.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
== *CHAPTER 1. Introduction*

[.text-justify]
This chapter introduces the *`LoongArch`* Architecture.
This chapter introduces the *`LoongArch`* architecture.

include::1.1-LoongArch_Architecture_Overview.adoc[]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
=== *2.2 Sign Extend & Zero Extend*

[.text-justify]
In *`LoongArch`* computing instructions, immediate values require both *`Sign-Extend`* and *`Zero-Extend`*.
In *`LoongArch`* computing instructions, immediate values require either *`Sign-Extend`* or *`Zero-Extend`*.

[.text-justify]
* 32-bit sign extend: Fills the high 32-n bits of an n-bit immediate with the highest bit of the immediate.
Expand All @@ -16,4 +16,4 @@ In *`LoongArch`* computing instructions, immediate values require both *`Sign-Ex
* 64 bit unsigned extend: Fill the high 64-n bits of the n-bit immediate with 0.

[.text-justify]
In the subsequent instructions, `*Sign*`*Extend*(x, len) represents sign extend, x represents the extend object, and len represents the number of digits in the final length of x after sign extend. `*Zero*`*Extend*(x, len) uses 0 to extend x to len.
In the subsequent instructions, `*Sign*`*Extend*(x, len) represents sign extension, where x is the object to be extended and len is the desired final length of x after the sign extension. ZeroExtend(x, len) extends x to len by filling the additional bits with 0.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ There are thirty-two General Registers (*`GR`*), denoted as *`$r0`*-*`$r31`*, wh
=== *3.2 PC Register*

[.text-justify]
There is only one *`PC`* that records the address of the current instruction. The *`PC`* register cannot be directly modified by instructions, it can only be indirectly modified by transfer instructions, exception trapping, and exception return instructions. *`PC`* registers can be directly read as source operands for some non transfer instructions. The width of *`PC`* always matches the width of *`GR`*.
There is only one *`PC`* that records the address of the current instruction. The *`PC`* register cannot be directly modified by instructions, it can only be indirectly modified by transfer instructions, exception trapping, and exception return instructions. *`PC`* registers can be directly read as source operands for some non-transfer instructions. The width of *`PC`* always matches the width of *`GR`*.
4 changes: 2 additions & 2 deletions adoc/CHAPTER-3.Register/3.2-Floating-Point_Register.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
=== *3.4 Condition Flag Register*

[.text-justify]
*`LoongArch`* has a total of 8 *`CFR`*, denoted as *`$fcc0`*-*`$fcc7`*, each of which can be read and written. The bit width of *`CFR`* is *1* bit. The result of the floating-point comparison will be written to the condition flag register, set to *1* when the comparison result is true, otherwise set to *0*. The judgment condition for floating-point branch instructions comes from the condition flag register.
*`LoongArch`* has a total of 8 *`CFRs`*, denoted as *`$fcc0`*-*`$fcc7`*, each of which can be read and written. The bit width of *`CFR`* is *1* bit. The result of the floating-point comparison is written to the condition flag register, which is set to 1 if the comparison result is true, and to 0 otherwise. The judgment condition for floating-point branch instructions comes from the condition flag register.

=== *3.5 Floating-Point Control Status Register*

[.text-justify]
*`LoongArch`* has a total of 4 *`FCSRs`*, denoted as *`$fcsr0`*-*`$fcsr3`*, with a bitwidth of 32 bits. Among them, *`$fcsr0`*-*`$fcsr3`* are aliases for the central domain of *`$fcsr0`*, that is, accessing *`$fcsr0`*-*`$fcsr3`* is actually accessing certain domains of *`$fcsr0`*. When the software writes *`$fcsr0`*-*`$fcsr3`*, the corresponding fields in *`$fcsr0`* are modified while the remaining bits remain unchanged.
*`LoongArch`* has a total of 4 *`FCSRs`*, denoted as *`$fcsr0`*-*`$fcsr3`*, with a bit width of 32 bits. Among them, *`$fcsr0`*-*`$fcsr3`* are aliases for the central domain of *`$fcsr0`*, meaning that accessing *`$fcsr0`*-*`$fcsr3`* actually accesses those specific domains of *`$fcsr0`*. When software writes to *`$fcsr0`*-*`$fcsr3`*, the corresponding fields in *`$fcsr0`* are modified, while the remaining bits remain unchanged.
14 changes: 7 additions & 7 deletions adoc/CHAPTER-3.Register/3.3-Register_Usage_Convention.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
===== *3.6.3.1 Zero Register*

[.text-justify]
The zero register, *`$r0`*, is a constant register that always returns *0* when read, regardless of what is written. To take the opposite number of a variable, you can use the zero register and the register where the variable is located to subtract, reducing the loading operation on the immediate *0*. *`$zero`* can complete some synthesis instructions, such as the macro instruction move in *`LoongArch`*.
The zero register, *`$r0`*, is a constant register that always returns *0* when read, regardless of what value is written to it. To take the opposite number of a variable, you can use the zero register and the register where the variable is located to subtract, reducing the loading operation on the immediate *0*. *`$zero`* can complete some synthesis instructions, such as the *`move`* macro instruction in *`LoongArch`*.

[source,asm]
----
Expand All @@ -113,13 +113,13 @@ move $t0, $t1 # or $t0, $t1, $zero
[.text-justify]
When *`LoongArch`*(*`LP64D ABI`*) makes a function call, registers *`$a0`* - *`$a7`* are used to pass 8 integer or pointer parameters. Registers *`$fa0`* - *`$fa7`* are used to pass 8 float-point parameters. Among them, *`$a0`* / *`$fa0`* and *`$a1`* / *`$fa1`* are also used to return values, and register *`$ra`* stores the return address.

===== *3.6.3.3 Temporary Register & Save Register*
===== *3.6.3.3 Temporary Register & Static Register*

[.text-justify]
Temporary registers are mainly used as temporary variables. When using these temporary registers in a function, there is no need to consider saving old values.

[.text-justify]
To save registers, the current function needs to ensure that the values of these registers are consistent with the function entry when the function returns. If one or more registers from *`$s0`* to *`$s8`* are to be used within a function, their old values need to be stored on the stack. And load the old value in the save register before the function returns.
For static registers, the current function needs to ensure that the values of these registers are consistent with their values at the function entry when the function returns. If one or more registers from *`$s0`* to *`$s8`* are used within a function, their old values need to be stored on the stack. The old values should be reloaded into the static register before the function returns.

[.text-justify]
Regarding the physical mapping of registers *`$rd`*, *`$rj`*, *`$rk`* in the assembly instruction description, the physical registers that can be used when writing assembly are as follows:
Expand All @@ -145,18 +145,18 @@ Regarding the physical mapping of registers *`$rd`*, *`$rj`*, *`$rk`* in the ass

^.^|*`$f24`* - *`$f31`*
^.^|*`$fs0`* - *`$fs7`*
.^|The role of temporary variables in functions does not require consideration of the preservation of old values.
.^|The function of a temporary variable requires storing its old value on the stack before use and restoring the old value before the function returns.
|===========================

===== *3.6.3.4 TP Register*

[.text-justify]
The *`$tp`* register is used to support thread local storage. *`TLS`* is a storage method for thread local variables, ensuring that variables are globally accessible within the thread, but cannot be accessed by other threads. *`LoongArch ABI`* specifically occupies a register to point to the *`TLS`* region of the current thread, with the aim of quickly locating and accessing variables within this region, and improving program execution efficiency. The user program is not recomened to modify this register.
The *`$tp`* register is used to support thread-local storage. *`TLS`* is a storage method for thread-local variables, ensuring that variables are accessible globally within the thread, but cannot be accessed by other threads. *`LoongArch ABI`* specifically occupies a register to point to the *`TLS`* region of the current thread, aiming to quickly locate and access variables within this region, thereby improving program execution efficiency. The user program is not recommended to modify this register.

===== *3.6.3.5 Function Stack & SP FP Register*

[.text-justify]
In a data structure, a stack is a dynamic storage space that only allows insertion and deletion operations on the same end. According to the principle of first in, last out, data is stored, where the data that enters first is pressed at the bottom of the stack, and the data that enters last is at the top of the stack. The function stack is mainly used to store local variables and related registers within a function, but its usage is not as strict as the stack in the data structure. Each function has different stack space sizes depending on the number of parameters and local variables.
In a data structure, a stack is a dynamic storage space that only allows insertion and deletion operations at the same end. Following the principle of first in, last out, data is stored such that the data that enters first is pressed at the bottom of the stack, while the data that enters last is at the top of the stack. The function stack is mainly used to store local variables and related registers within a function, but its usage is not as strict as the stack in the data structure. Each function has different stack space sizes depending on the number of parameters and local variables.

[.text-justify]
The frame pointer of a function with immutable stack frames is *`$sp`*; The frame pointer of the variable stack frame function is *`$fp`* . In the entire function, the determination of the frame pointer, the storage register, and the backup of *`$ra`* (for non leaf functions) are in a basic block called prologue. Once the frame pointer is determined, it will not change until the function returns.
The frame pointer of a function with immutable stack frames is *`$sp`*, while the frame pointer of the variable stack frame function is *`$fp`* . Within a function, the determination of the frame pointer, the storage register, and the backup of *`$ra`* (for non-leaf functions) are in a basic block called prologue. Once the frame pointer is determined, it will not change until the function returns.
6 changes: 3 additions & 3 deletions adoc/CHAPTER-4.Address/4.1-Addressing_Range.adoc
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
=== *4.1 Address Range*

[.text-justify]
The memory address space on *`LoongArch`* is a continuous linear address space, which is addressed in bytes.
The memory address space on *`LoongArch`* is a continuous linear address space that is addressed in bytes.

[.text-justify]
In *`LA32`*, the specification of the memory address space that application can access is: 0-2^*`31`*^-1.
In *`LA32`*, the specification for the accessible memory address space for applications is: 0-2^*`31`*^-1.

[.text-justify]
In *`LA64`*, the range of memory address space accessible by application is: 0-2^*`VALEN-1`*^-1. Generally *`VALEN`* is in the range of [*`40`*,*`48`*]. Application can determine the specific value of *`VALEN`* by executing the *`CPUCFG`* instruction to read the *`VALEN`* field of the 0x1 configuration word.
In *`LA64`*, the range of memory address space accessible by application is: 0-2^*`VALEN-1`*^-1, where *`VALEN`* is generally in the range of [*`40`*,*`48`*]. Applications can determine the specific value of *`VALEN`* by executing the *`CPUCFG`* instruction to read the *`VALEN`* field of the 0x1 configuration word.

[.text-justify]
When the virtual address of the instruction fetch or memory access instruction in the application exceeds the above range, ADEF or ADEM will be triggered.
Loading

0 comments on commit 005a9cb

Please sign in to comment.