diff --git a/Makefile b/Makefile index decc6be..57b2b25 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index 00a6db1..f6f2ba4 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/adoc/CHAPTER-1.Introduction/1.1-LoongArch_Architecture_Overview.adoc b/adoc/CHAPTER-1.Introduction/1.1-LoongArch_Architecture_Overview.adoc index 693da08..59b0a0c 100644 --- a/adoc/CHAPTER-1.Introduction/1.1-LoongArch_Architecture_Overview.adoc +++ b/adoc/CHAPTER-1.Introduction/1.1-LoongArch_Architecture_Overview.adoc @@ -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`*). diff --git a/adoc/CHAPTER-1.Introduction/1.Introduction.adoc b/adoc/CHAPTER-1.Introduction/1.Introduction.adoc index 3588077..1204c70 100644 --- a/adoc/CHAPTER-1.Introduction/1.Introduction.adoc +++ b/adoc/CHAPTER-1.Introduction/1.Introduction.adoc @@ -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[] diff --git a/adoc/CHAPTER-2.Data_Representation/2.2-Sign_Entend_Zero_Extend.adoc b/adoc/CHAPTER-2.Data_Representation/2.2-Sign_Entend_Zero_Extend.adoc index 9c5e963..78495da 100644 --- a/adoc/CHAPTER-2.Data_Representation/2.2-Sign_Entend_Zero_Extend.adoc +++ b/adoc/CHAPTER-2.Data_Representation/2.2-Sign_Entend_Zero_Extend.adoc @@ -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. @@ -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. diff --git a/adoc/CHAPTER-3.Register/3.1-Integer_General_Purpose_Register.adoc b/adoc/CHAPTER-3.Register/3.1-Integer_General_Purpose_Register.adoc index fc606eb..80beb27 100644 --- a/adoc/CHAPTER-3.Register/3.1-Integer_General_Purpose_Register.adoc +++ b/adoc/CHAPTER-3.Register/3.1-Integer_General_Purpose_Register.adoc @@ -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`*. diff --git a/adoc/CHAPTER-3.Register/3.2-Floating-Point_Register.adoc b/adoc/CHAPTER-3.Register/3.2-Floating-Point_Register.adoc index c7ffad6..6db9113 100644 --- a/adoc/CHAPTER-3.Register/3.2-Floating-Point_Register.adoc +++ b/adoc/CHAPTER-3.Register/3.2-Floating-Point_Register.adoc @@ -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. diff --git a/adoc/CHAPTER-3.Register/3.3-Register_Usage_Convention.adoc b/adoc/CHAPTER-3.Register/3.3-Register_Usage_Convention.adoc index 53ff3b3..f8eac08 100644 --- a/adoc/CHAPTER-3.Register/3.3-Register_Usage_Convention.adoc +++ b/adoc/CHAPTER-3.Register/3.3-Register_Usage_Convention.adoc @@ -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] ---- @@ -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: @@ -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. diff --git a/adoc/CHAPTER-4.Address/4.1-Addressing_Range.adoc b/adoc/CHAPTER-4.Address/4.1-Addressing_Range.adoc index aed75ed..cdb61ad 100644 --- a/adoc/CHAPTER-4.Address/4.1-Addressing_Range.adoc +++ b/adoc/CHAPTER-4.Address/4.1-Addressing_Range.adoc @@ -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. diff --git a/adoc/CHAPTER-5.Assembler_Directives/5.1-Symbol_Define_Assembler_Instruction.adoc b/adoc/CHAPTER-5.Assembler_Directives/5.1-Symbol_Define_Assembler_Instruction.adoc index 486f9db..8d14af2 100644 --- a/adoc/CHAPTER-5.Assembler_Directives/5.1-Symbol_Define_Assembler_Instruction.adoc +++ b/adoc/CHAPTER-5.Assembler_Directives/5.1-Symbol_Define_Assembler_Instruction.adoc @@ -1,12 +1,12 @@ === *5.1 Symbol Definition Directives* [.text-justify] -If an identifier is not defined to the assembler (only referenced), the assembler assumes that the identifier is an external symbol. The assembler treats the identifier like a *`.globl`* pseudo-operation. If the identifier is defined to the assembler and the identifier has not been specified as global, the assembler assumes that the identifier is a local symbol. +If an identifier is referenced but not defined in the assembler, it is treated as an external symbol. In this case, the assembler handles the identifier as if it were declared with the *`.globl`* pseudo-operation. Conversely, if the identifier is defined but not specified as global, the assembler treats it as a local symbol. ==== *5.1.1 Set Symbol Type* [.text-justify] -The assembler directive that defines a symbol type is *`.type`*, which is often followed by types *`@function`* and *`@object`*, respectively, indicating that the current symbol is a function and a variable. +The assembler directive that defines a symbol type is *`.type`*, which is often followed by the types *`@function`* or *`@object`*, indicating that the current symbol is a function or a variable, respectively. [source,asm] ---- @@ -17,7 +17,7 @@ The assembler directive that defines a symbol type is *`.type`*, which is often ==== *5.1.2 Set Symbol Size* [.text-justify] -The assembler directive *`.size`* name, expression is used to set the size of symbols, where name is the symbol name. When setting the variable size, expression is a positive integer. When setting the function size, expression is usually a "*`.-name`*" expression. +The assembler directive *`.size name, expression`* is used to set the size of symbols, where *`name`* is the symbol name. When setting the size of a variable, *`expression`* is a positive integer. When setting the size of a function, *`expression`* is usually a "*`.-name`*" expression. [source,asm] ---- @@ -28,7 +28,7 @@ The assembler directive *`.size`* name, expression is used to set the size of sy ==== *5.1.3 Set Symbol Align* [.text-justify] -The assembler directive *`.align`* expr is used to specify the alignment of symbols, where expr is a positive integer used to indicate the alignment of subsequent data storage addresses in the target file. +The assembler directive *`.align expr`* is used to specify the alignment of symbols, where *`expr`* is a positive integer that indicates the alignment of subsequent data storage addresses in the target file. [source,asm] ---- @@ -36,7 +36,7 @@ The assembler directive *`.align`* expr is used to specify the alignment of symb ---- [.text-justify] -Pad the location counter (in the current subsection) to a particular storage boundary. Expr is a positive integer indicating the alignment of the data storage address in the target file. In *`LoongArch`*: +Pad the location counter (in the current subsection) to a particular storage boundary. *`Expr`* is a positive integer that indicates the alignment of the data storage address in the target file. In *`LoongArch`*: [source,asm] ---- @@ -56,18 +56,18 @@ In order to simplify the hardware design between processors and memory systems, * To read or write a *`doubleword`* (*`8 bytes`*) of data from memory, the access address must be a multiple of *8*. [.text-justify] -*`$r5`* = *`0x120000000`*, *`ld.w`* *`$r4`*, *`$r5`*, *`0x3`* Address *`0x120000003`* Not divisible by *4*, therefore non aligned access. *`ld.w`* *`$r4`*, *`$r5`*, *`0x8`* Address *`0x120000008`* It can be divided by *4*, so it is an aligned access. *`ld.d`* *`$r4`*, *`$r5`*, *`0x5`* Address *`0x120000005`* Not divisible by *4*, therefore non aligned access. +*`$r5`* = *`0x120000000`*, *`ld.w`* *`$r4`*, *`$r5`*, *`0x3`*: The address *`0x120000003`* is not divisible by *4*, therefore non-aligned access. *`ld.w`* *`$r4`*, *`$r5`*, *`0x8`*: The address *`0x120000008`* is divisible by *4*, so it is an aligned access. *`ld.d`* *`$r4`*, *`$r5`*, *`0x5`*: The address *`0x120000005`* is not divisible by *4*, thus it is also a non-aligned access. [.text-justify] -*`LoongArch`* supports hardware processing of non aligned memory data access. Although there is non aligned access in the above example, the processor can still function properly and obtain correct results without throwing non aligned exceptions. However, for better performance, it is recommended to align the data as much as possible. Generally, the compiler will automatically align the data. +*`LoongArch`* supports hardware processing of non-aligned memory data access. Although there is non-aligned access in the above example, the processor can still function properly and produce correct results without throwing non-aligned exceptions. However, for better performance, it is recommended to align the data as much as possible. Generally, the compiler will automatically align the data. [.text-justify] -In the above command, different architectures of .align have different definitions of expr, and two other variants, *`.balgin`* and *`.p2align`*, can be used. The instruction *`.balgin`* 4 represents 4-byte alignment in any architecture. +In the above command, different architectures of .align have different definitions of *`expr`*. Additionally, two other variants, *`.balign`* and *`.p2align`*, can also be used. The instruction *`.balign 4`* represents 4-byte alignment in any architecture. * .align https://sourceware.org/binutils/docs/as/Align.html [.text-justify] -Two other variants, *`.balign`* and *`.p2align`*, can be used. Regarding *`.balgin`* and *`.p2align`* : +Two other variants, *`.balign`* and *`.p2align`*, can be used. Regarding *`.balign`* and *`.p2align`* : * .balign https://sourceware.org/binutils/docs/as/Balign.html @@ -76,7 +76,7 @@ Two other variants, *`.balign`* and *`.p2align`*, can be used. Regarding *`.balg ==== *5.1.4 Set Symbol Location* [.text-justify] -When defining a variable or function symbol in the assembly source file, its scope should also be declared to identify the scope of the current symbol. By default, the current symbol scope is not specified, and the symbol scope is visible within the current assembly source file. Other compiler instructions that need to be used in other situations include: +When defining a variable or function symbol in the assembly source file, its scope should also be declared to identify the scope of the current symbol. By default, the current symbol's scope is not specified and is visible within the current assembly source file. Other compiler instructions that need to be used in other situations include: [source,asm] ---- @@ -87,10 +87,10 @@ When defining a variable or function symbol in the assembly source file, its sco ---- [.text-justify] -*`.globl`* / *`.global`* specifies the symbol as a global variable or non-static member function, which is globally visible and visible to other source files in the linker. +The *`.globl`* / *`.global`* directive specifies a symbol as a global variable or non-static member function, making it accessible to other source files during the linking process. [.text-justify] -The *`.common`* declaration is a universal symbol, similar to an uninitialized global variable in C language. A universal symbol with the same name that appears in multiple assembly source files may be merged during the compiler's compilation phase, resulting in the preservation of the one with the largest footprint. +The *`.common`* declaration is a universal symbol, similar to an uninitialized global variable in the C language. If a universal symbol with the same name appears in multiple assembly source files, they may be merged during the compiler's compilation phase, resulting in the preservation of the one with the largest footprint. [.text-justify] -*`.local`* is used to declare an uninitialized local static variable definition similar to that in a language. +The *`.local`* directive is used to declare an uninitialized local static variable, similar to that in the C language. diff --git a/adoc/CHAPTER-5.Assembler_Directives/5.2-Logic_Control_Assembler_Instruction.adoc b/adoc/CHAPTER-5.Assembler_Directives/5.2-Logic_Control_Assembler_Instruction.adoc index 17a5526..81a8c4a 100644 --- a/adoc/CHAPTER-5.Assembler_Directives/5.2-Logic_Control_Assembler_Instruction.adoc +++ b/adoc/CHAPTER-5.Assembler_Directives/5.2-Logic_Control_Assembler_Instruction.adoc @@ -1,12 +1,12 @@ === *5.2 Logic Control Directives* [.text-justify] -The assembler will translate the assembly instructions into machine instructions and store them in the target file. The assembler directive is different from the assembly instruction, which is used to guide the assembler on how to define variables and functions, and how to store assembly instructions in the target file. The assembler directive is the instruction that guides the work of the assembler. +The assembler translates assembly instructions into machine instructions and stores them in the target file. Assembler directives are different from assembly instructions; they guide the assembler on how to define variables and functions, and how to store assembly instructions in the target file. Assembler directives instruct the assembler on its operation. ==== *5.2.1 Set Symbol Data Storage Segment* [.text-justify] -Use assembler directives such as .data subsection and *`.text`* subsection in the assembly source file to specify the data and code segments where the following statements are stored in the target file. When it is necessary to specify a more refined segment type. You can use the *`.section`* name. +Use assembler directives such as the *`.data`* subsection and the *`.text`* subsection in the assembly source file to specify the data and code segments where the following statements are stored in the target file. When a more refined segment type needs to be specified, you can use the *`.section`* name directive. [source,asm] ---- @@ -33,7 +33,7 @@ The assembler directive *`.set`* symbol, expression is used for constant setting ==== *5.2.3 Conditional Compilation* [.text-justify] -In conjunction with constant settings, use the assembler directives *`.if`*, *`.else`*, and *`.endif`* to achieve conditional compilation. +In conjunction with constant settings, the assembler directives *`.if`*, *`.else`*, and *`.endif`* can be used to achieve conditional compilation. [source,asm] ---- @@ -54,7 +54,7 @@ main: ---- [.text-justify] -For conditional compilation, preprocessing commands such as *`#ifdef`*, *`#else`*, and *`#endif`* in C language can also be directly used in the asm source file. When using the C language pre-processing command, the assembly source file cannot be compiled directly with the assembler, but needs to call the compiler's preprocessing tool in advance to translate the pre-processing command. +For conditional compilation, preprocessing commands such as *`#ifdef`*, *`#else`*, and *`#endif`* in the C language can also be used directly in the assembly source file. When using these C language preprocessing commands, the assembly source file cannot be compiled directly with the assembler; instead, it needs to be processed first using the compiler's preprocessing tool to translate the preprocessing commands. .Condition [options="header"] @@ -94,7 +94,7 @@ For conditional compilation, preprocessing commands such as *`#ifdef`*, *`#else` ==== *5.2.4 Compile Debug* [.text-justify] -The information output instructions that can be used during the compilation process of the assembler include: +The information output instructions that can be used during the assembly process of the assembler include: [.text-justify] * *`.print`* string @@ -108,22 +108,22 @@ The information output instructions that can be used during the compilation proc ===== *5.2.4.1 .print string* [.text-justify] -Will cause the assembler to output a string on standard output. +This will cause the assembler to output a string to the standard output. ===== *5.2.4.2 .fail expression* [.text-justify] -An error or warning message will be generated, and when the expression value is greater than or equal to 500, the assembler will output a warning message; When the value of expression is less than 500, the assembler will output an error message. The default value of expression is 0, and the *`.fail`* parameter can be written directly and left blank. +An error or warning message will be generated. When the expression value is greater than or equal to 500, the assembler will output a warning message; if expression value is less than 500, the assembler will output an error message. The default value of expression is 0, and the *`.fail`* parameter can be written directly and left blank. ===== *5.2.4.3 .error string & .err* [.text-justify] -*`.err`* can output a default error message during the assembly process. If you want to customize the error message type, you can use the *`.error`* string directive. +*`.err`* can output a default error message during the assembly process. If you want to customize the error message type, you can use the *`.error`* string directive to specify your own message. ==== *5.2.5 File Include* [.text-justify] -There are two ways to reference other files in the assembly source file. One method is to use the assembler directive *`.include`* '*`file`*', which defaults to the current directory as the reference file path. When the path of the referenced file is not in the same directory, the search path can be controlled through the compiler's command-line option parameter '*`- I`*'; Another method is to use the C language preprocessing command *`#include`*, which requires the assembler file to be *`.S`* and preprocessed through the front-end preprocessing tool. +There are two ways to reference other files in the assembly source file. One method is to use the assembler directive *`.include`* '*`file`*', which defaults to the current directory for the reference file path. If the referenced file is not in the same directory, the search path can be controlled through the compiler's command-line option parameter '*`- I`*'. The other method is to use the C language preprocessing command *`#include`*, which requires the assembler file to have a *`.S`* and to be preprocessed by the front-end preprocessing tool. [source,asm] ---- @@ -139,7 +139,7 @@ test: ==== *5.2.6 Loop Unrolling* [.text-justify] -assembler directives *`.rept`* count and *`.endr`* can be used to loop through their internal statements count times. +The assembler directives *`.rept count`* and *`.endr`* can be used to loop through their internal statements count times. [source,asm] ---- @@ -149,10 +149,10 @@ nop ---- [.text-justify] -The above code is equivalent to notifying the assembler to generate three nop instructions in the target file. When it is necessary to insert different numbers of your nop instructions according to the actual situation to achieve address alignment, using the loop unrolling instruction is very convenient. +The above code is equivalent to instruct the assembler to generate three *`nop`* instructions in the target file. When it is necessary to insert a different number of *`nop`* instructions for address alignment based on the actual situation, using the loop unrolling directive is very convenient. [.text-justify] -assembler directives *`.irp`* symbol, values and *`.endr`* can loop through its internal statements. +The assembler directives *`.irp symbol, values`*  and *`.endr`* can also be used to loop through their internal statements. [source,asm] ---- @@ -179,10 +179,10 @@ st.d $r12, $sp, 0x60 ==== *5.2.7 Macro Define* [.text-justify] -The assembler directive *`.macro`* name args is similar in function to the macro definition function in C language, where name is the macro name, args is the parameter, and ends with *`.endm`* . +The assembler directive *`.macro name args`* functions similarly to the macro definition in the C language, where *`name`* is the macro name, *`args`* is the parameter, and ends with *`.endm`* . [.text-justify] -For example, implementing a macro definition that can generate different numbers of nop instructions based on different parameters: +For example, here's how you can implement a macro definition that generates a different number of *`nop`* instructions based on different parameters: [source,asm] ---- @@ -195,10 +195,78 @@ nop ---- [.text-justify] -Here, *`.text`* is used to indicate that the following instructions are stored in the code snippet of the target file. Macro name is *`INSERT_NOP`*, parameter is a. The format for using parameters in the macro definition body is "parameter", such as a. The parameters of the macro can be 0 or multiple. When there are multiple parameters, use commas or spaces to separate them. When the program is in use, simply call the macro. +Here, *`.text`* is used to indicate that the following instructions are stored in the code section of the target file. The macro name is *`INSERT_NOP`*, and the parameter is *`a`*. The format for using parameters in the macro definition body is "parameter", such as *`a`*. The parameters of the macro can be 0 or multiple, with commas or spaces used to separate them when there are multiple parameters. When the program is in use, simply call the macro. [source,asm] ---- INSERT_NOP 3 INSERT_NOP 7 ---- + +==== *5.2.8 CFI Directives* + +[.text-justify] +* The registers in CFI do not use "*`$r1`*" or "*`r1`*", they are represented only by their numbers, such as "*`1`*" for "*`$r1`*" . + +==== *5.2.9 .option Directive* + +[.text-justify] +In some cases, we may want to use different options only for certain assembly, so the *`.option`* directive is added to control the assembler options. + +*Syntax:* + + .option option1 [, option2 , ...] + +[.text-justify] +The *`.option`* directive selects options for the assembler output listing. The options must be separated by commas; each option selects a listing feature. These are four valid options: + +[source] +---- +push limits the scope of the option change. +relax causes the R_LARCH_RELAX to be emitted. +norelax suppresses the R_LARCH_RELAX to be emitted. +pop limits the scope of the option change. +---- + +[.text-justify] +*`.option push`* and *`.option pop`* limit the scope of the option change, and other assembly will not be affected. Using *`.option pop`* correctly restores all target features to their state at the point where *`.option pop`* was last used. *`.option relax`* causes *`R_LARCH_RELAX`* to be emitted, and *`.option norelax`* suppresses it. + +[.text-justify] +Here is an example of le relax: + +[source,asm] +---- + .text +L1: + .option push + + .option norelax + lu12i.w $t0,%le_hi20(s) + addi.d $t0,$t0,le_lo12(s) + + .option relax + lu12i.w $t0,%le_hi20(s) + addi.d $t0,$t0,le_lo12(s) + + .option pop +---- + +[.text-justify] +After assembly: + +[source,asm] +---- +Disassembly of section .text: + +0000000000000000 : + 0: 1400000c lu12i.w $t0, 0 + 0: R_LARCH_TLS_LE_HI20 s + 4: 02c0018c addi.d $t0, $t0, 0 + 4: R_LARCH_TLS_LE_LO12 s + 8: 1400000c lu12i.w $t0, 0 + 8: R_LARCH_TLS_LE_HI20 s + 8: R_LARCH_RELAX *ABS* + c: 02c0018c addi.d $t0, $t0, 0 + c: R_LARCH_TLS_LE_LO12 s + c: R_LARCH_RELAX *ABS* +---- diff --git a/adoc/CHAPTER-5.Assembler_Directives/5.Assembler_Directives.adoc b/adoc/CHAPTER-5.Assembler_Directives/5.Assembler_Directives.adoc index fc8a539..914fda9 100644 --- a/adoc/CHAPTER-5.Assembler_Directives/5.Assembler_Directives.adoc +++ b/adoc/CHAPTER-5.Assembler_Directives/5.Assembler_Directives.adoc @@ -3,7 +3,7 @@ [.text-justify] This chapter mainly describes assembler commands and assembler instructions. -For more command line parameters of the assembler, please refer to the documentation for the assembler on the *`GCC`* and *`LLVM`* official websites. +For more command line parameters of the assembler, please refer to the documentation for the assembler on the official *`GCC`* and *`LLVM`* websites. include::5.1-Symbol_Define_Assembler_Instruction.adoc[] diff --git a/adoc/CHAPTER-6.ASM_File_&_ELF_File/6.ASM_File_&_ELF_File.adoc b/adoc/CHAPTER-6.ASM_File_&_ELF_File/6.ASM_File_&_ELF_File.adoc index 74abf77..769c07f 100644 --- a/adoc/CHAPTER-6.ASM_File_&_ELF_File/6.ASM_File_&_ELF_File.adoc +++ b/adoc/CHAPTER-6.ASM_File_&_ELF_File/6.ASM_File_&_ELF_File.adoc @@ -35,13 +35,13 @@ main: ---- [.text-justify] -A *`relocatable file`* holds code and data suitable for linking with other object files to create an executable or a shared object file. +A *`relocatable file`* holds code and data that are suitable for linking with other object files to create an executable or a shared object file. [.text-justify] -An *`executable file`* holds a program suitable for execution; the file specifies how exec(LoongArch) creates a program's process image. +An *`executable file`* holds a program that is suitable for execution; the file specifies how exec(LoongArch) creates a program's process image. [.text-justify] -A *`shared object file`* holds code and data suitable for linking in two contexts. First, the link editor see ld(LoongArch) processes the shared object file with other relocatable and shared object files to create another object file. Second, the dynamic linker combines it with an executable file and other shared objects to create a process image. +A *`shared object file`* holds code and data that are suitable for linking in two contexts. First, the link editor, as seen in ld(LoongArch), processes the shared object file with other relocatable and shared object files to create another object file. Second, the dynamic linker combines it with an executable file and other shared objects to create a process image. [.text-justify] -For more information on ELF files, please refer to link:https://www.sco.com/developers/gabi/latest/contents.html[SysV gABI] and http://sysdev.loongson.cn/attachments/download/91249/la-abi.pdf[LoongArch Application Binary Interface manual]. +For more information on ELF files, please refer to link:https://www.sco.com/developers/gabi/latest/contents.html[SysV gABI] and https://github.com/loongson/la-abi-specs/releases/tag/v2.30/la-abi.pdf[LoongArch Application Binary Interface manual]. diff --git a/adoc/CHAPTER-7.Extended_Asm/7.Extended_Asm.adoc b/adoc/CHAPTER-7.Extended_Asm/7.Extended_Asm.adoc index e9cd13b..fff8487 100644 --- a/adoc/CHAPTER-7.Extended_Asm/7.Extended_Asm.adoc +++ b/adoc/CHAPTER-7.Extended_Asm/7.Extended_Asm.adoc @@ -1,17 +1,17 @@ == *CHAPTER 7. Inline Assembly* [.text-justify] -The asm keyword allows you to embed assembler instructions within C code. Compiler provides two forms of inline asm statements. A basic assembly statement is one with no operands, and an Extended assembly statement which includes one or more operands to interact with C variables. +The asm keyword allows you to embed assembler instructions within C code. The compiler provides two forms of inline assembly statements: basic assembly statements, which have no operands, and extended assembly statements, which include one or more operands to interact with C variables. [.text-justify] -In the process of program development, assembly language can achieve functions that cannot be achieved by C language in certain situations, which requires the use of extended asm. +In the process of program development, assembly language can achieve functionalities that cannot be accomplished by C language in certain situations, which requires the use of extended asm. === *7.1 Basic Assembly* -Refer to the "Instruction Set" section in Programming Manual document to get details of all instructions. +Refer to the "Instruction Set" section in the Programming Manual document for details on all instructions. [.text-justify] -Here is a example: +Here is an example: Inline assembly code is used to write pure assembly code in a *`C/C++`* program: @@ -20,18 +20,18 @@ Inline assembly code is used to write pure assembly code in a *`C/C++`* program: int main() { asm volatile("move $r23, $r24"); - asm volatile("addi $r23, $r24, 1"); + asm volatile("addi.w $r23, $r24, 1"); } ---- -Use in block of instructions, note the *`\n\t`* at the end of each instruction: +Use the following format in the block of instructions, noting that *`\n\t`* should be included at the end of each instruction: [source] ---- int main() { asm volatile("move $r23, $r24\n\t" - "addi $r23, $r24, 1\n\t"); + "addi.w $r23, $r24, 1\n\t"); } ---- @@ -39,9 +39,9 @@ int main() We will write a simple code to: -* Load values from 2 addresses *`0x20001000`* and *`0x20001004`* +* Load values from two addresses: *`0x20001000`* and *`0x20001004`* -* Store the sum of those numbers to a new address *`0x20001008`* +* Store the sum of these values at a new address: *`0x20001008`* [source] ---- @@ -56,7 +56,7 @@ int main(void) { === *7.2 Extended Assembly* -The Inline Assembly full syntax is : +The full syntax of Inline Assembly is: [source] ---- @@ -87,10 +87,10 @@ asm volatile("move $r23, $r24":::); *`OutputOperands`* : -* A comma-separated list of the C variables modified by the instructions in the Assembler Template. An empty list is permitted. +* A comma-separated list of C variables modified by the instructions in the Assembler Template. An empty list is permitted. [.text-justify] -Here is a example: +Here is an example: [source] ---- @@ -103,22 +103,22 @@ asm volatile("add.w %0 , %1 , %2 \n\t" ---- [.text-justify] -In the above example, the instructions and operands used by extended asm are first described. By using '*`:`*' to inform the compiler of the meaning of this assembly instruction and the number of operands required by the assembly instruction. '*`=r`*' and '*`r`*' indicate that this is a register operand, referred to as an operand constraint. '*`r`*' represents a fixed point register operand, '*`=`*' represents an output operand, otherwise it is an input operand. After containing the above information, the compiler can understand how to convert this extended asm into actual assembly instructions. +In the above example, the instructions and operands used by extended asm are first described. The '*`:`*' character informs the compiler aboout the meaning of this assembly instruction and the number of operands required. The constraints '*`=r`*' and '*`r`*' indicate that these are register operands, with '*`r`*' representing a fixed-point register operand and '*`=`*' indicating an output operand. In constrast, if there is no *`=`*, it represents an input operand. With this information, the compiler can understand how to convert the extended asm into actual assembly instructions. -If the extended asm is bound to a register variable, it should be noted that if the extended asm uses a temporary register to save the result, or if a register variable is bound to a temporary register, it may be changed during the function call, as the value of the temporary register will not be maintained by the system during the function call and manual instructions need to be added for maintenance. So it is recommended to use save registers as much as possible in extended asm. +If the extended asm is bound to a register variable, it's important to note that if the extended asm uses a temporary register to store the result, or if a register variable is bound to a temporary register, that value may change during the function call. This is because the value of the temporary register will not be maintained by the system during the function call, so manual instructions need to be added for maintenance. Therefor, it is recommended to use saved registers as much as possible in extended asm. *`InputOperands`* : * A comma-separated list of C expressions read by the instructions in the AssemblerTemplate. An empty list is permitted. [.text-justify] -* Sometimes we need to use designated registers in assembly instructions. A typical example is a system call, where the system call number and parameters must be placed in the designated registers. +* Sometimes we need to use designated registers in assembly instructions. A typical example is a system call, where the system call number and parameters must be placed in specific designated registers. [.text-justify] * To achieve this goal, we need to use extended syntax when declaring variables. [.text-justify] -Here is a example: +Here is an example: [source] ---- @@ -131,17 +131,17 @@ asm volatile("addi.w %0,%1,0xf\n\t" ---- [.text-justify] -If the register used by extended asm is specified in the instruction description, it should be noted that general-purpose registers can be represented as *`$GR`* or *`GR`*, the '*`$`*' symbol is not necessary, floating-point registers must contain the '*`$`*' symbol, and floating-point registers must be represented as *`$FR`*. Please do not use its alias for *`FR`* . +If the registers used in extended assembly are specified in the instruction description, it should be noted that general-purpose registers can be represented as either *`$GR`* or *`GR`*; the '*`$`*' symbol is not necessary. However, floating-point registers must contain the '*`$`*' symbol and must be represented as *`$FR`*. Please do not use its alias for *`FR`* . *`Clobbers`* : * A comma-separated list of registers or other values changed by the AssemblerTemplate, beyond those listed as outputs. An empty list is permitted. [.text-justify] -* Some assembly instructions may implicitly modify some registers that are not in the instruction operand. In order to make the compiler aware of this situation, the implicit change of register rules is listed after the input rules. +* Some assembly instructions may implicitly modify some registers that are not in the instruction operand. In order to make the compiler aware of this situation, the rules for implicit register changes are listed after the input rules. [.text-justify] -Here is a example: +Here is an example: [source] ---- @@ -152,7 +152,7 @@ asm volatile("xor $r25, $r25, %0\n\t" *`GotoLabels`* : [.text-justify] -With extended asm you can read and write C variables from assembler and perform jumps from assembler code to C labels. Extended asm syntax uses colons ('*`:`*') to delimit the operand parameters after the assembler template: +With extended asm, you can read and write C variables from assembler and perform jumps from assembler code to C labels. The extended asm syntax uses colons ('*`:`*') to delimit the operand parameters after the assembler template: [source] ---- @@ -164,7 +164,7 @@ asm goto( AssemblerTemplate ---- [.text-justify] -Here is a example: +Here is an example: [source] ---- @@ -182,12 +182,12 @@ labelbeqz: This is useful for above cases: -* Move the content of C variable to an *`LoongArch`* register. -* Move the content of an *`LoongArch`* register to a C variable. -* Access assembly instructions that are not readily available to C programs. +* Move the content of a C variable to a *`LoongArch`* register. +* Move the content of a *`LoongArch`* register to a C variable. +* Access assembly instructions that are not readily available in C programs. [.text-justify] -For more extended asm related content, please refer to: +For more content related to extended asm, please refer to: [.text-justify] * link:https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html[Basic Asm — Assembler Instructions Without Operands] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction.adoc index c69e118..354f7d1 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction.adoc @@ -1,7 +1,7 @@ ==== *8.1.1 Base Integer Instruction* [.text-justify] -This section will describe the functionality of application level basic integer instructions in the *`LA64`* architecture. For the *`LA32`* architecture, only one subset needs to be implemented. Due to the fact that the bit width of *`GR`* under the *`LA32`* architecture is only 32 bits, the signed extension operation in the subsequent instruction description of "writing the 32-bit result signed extension to the general register *`$rd`*" is not required. +This section will describe the functionality of application-level basic integer instructions in the *`LA64`* architecture. For the *`LA32`* architecture, only one subset needs to be implemented. Due to the fact that the bit width of *`GR`* under the *`LA32`* architecture is only 32 bits, the signed extension operation mentioned in the subsequent instruction description-"writing the 32-bit result signed extension to the general register *`$rd`*"-is not required. include::8.1.1-Base_Integer_Instruction/8.1.1.1-Arithmetic_Operation_Instructions.adoc[] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.1-Arithmetic_Operation_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.1-Arithmetic_Operation_Instructions.adoc index e060574..1e7990d 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.1-Arithmetic_Operation_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.1-Arithmetic_Operation_Instructions.adoc @@ -83,6 +83,8 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.1`* . ^.^|*`si16`* |=========================== +<<< + *Description :* [grid=none] @@ -98,7 +100,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.1`* . <.^|*`$rd`*[63:0] = *`$rj`*[63:0] `*+*` `*Sign*`*Extend* (*`si12`*, 64) |=========================== -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] [grid=none] [frame=none] @@ -109,7 +111,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.1`* . <.^|*`$rd`*[63:0] = *`$rj`*[63:0] *`+`* `*Sign*`*Extend* ({*`si16`*, 16'b0}, 64) |=========================== -* *`si16`* : 16 bit immediate, Signed value range(*`integer`*) : [*`-32768`, `32767`*] or [*`-0x8000`, `0x7fff`*] +* *`si16`* : 16-bit immediate, signed value range(*`integer`*) : [*`-32768`, `32767`*] or [*`-0x8000`, `0x7fff`*] ** The input *`si16`* is the value *`before`* the *`offset operation`*. @@ -119,14 +121,14 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.1`* . ---- li.w $r24, 1024 # $24 = 1024 addi.w $r23, $r24, 1024 # $23 = 2048 -addi.d $r25, $r24, 2048 # $25 = 4096 +addi.d $r25, $r23, 2048 # $25 = 4096 li.d $r26, 8 # $26 = 8 addu16i.d $r27, $r26, -32768 # $27 = -2147483640 ---- * *Explanation :* -** The LA64 of *`-32768`* is *`0x8000`*, shifts the 16-bit immediate sil6 logic to the left by 16 bits, shifts the 16-bit immediate *`si16`* logic to the left by 16 bits, the result is *`0x80000000`* or *`-2147483648`* . Expand the range of immediate numbers. +** The LA64 of *`-32768`* is *`0x8000`*. Shifting the 16-bit immediate *`sil6`* logic to the left by 16 bits, as well as shifting the 16-bit immediate *`si16`* logic to the left by 16 bits, results in *`0x80000000`* or *`-2147483648`* . This expands the range of immediate numbers. [NOTE] @@ -185,8 +187,12 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.2`* . [source] ---- li.w $r24, 8 # $r24 = 8 +---- + +[source] +---- li.w $r25, 4 # $r25 = 4 -alsl.w $r23, $r24, $r25, 2 # $r23 = 8<<2 + 4 = 36 +alsl.w $r23, $r24, $r25, 2 # $r23 = (8<<2) + 4 = 36 ---- [NOTE] @@ -234,7 +240,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.3`* . <.^|*`$rd`*[63:0] = {`*Sign*`*Extend* (*`si20`*, 32), *`$rd`*[31:0]} |=========================== -* *`si20`* : 20 bit immediate, Signed value range(*`integer`*) : [*`-524288`, `524287`*] or [*`-0x80000`, `0x7ffff`*] +* *`si20`* : 20-bit immediate, signed value range(*`integer`*) : [*`-524288`, `524287`*] or [*`-0x80000`, `0x7ffff`*] [grid=none] [frame=none] @@ -245,7 +251,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.3`* . <.^|*`$rd`*[63:0] = {*`si12`*, *`$rj`*[51:0]} |=========================== -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] *Usage :* [source] @@ -256,7 +262,7 @@ lu32i.d $r23, 0xcba98 # $r23 = 0xfffcba9876543210 lu52i.d $r23, $r23, 0xfed # $r23 = 0xfedcba9876543210 ---- -The loading of immediate number in *`LoongArch`* is very cumbersome, and pseudo instructions are generally used when writing assembly files: +The loading of immediate number in *`LoongArch`* is very cumbersome, which is why pseudo-instructions are commonly used when writing assembly files: [grid=none] [frame=none] @@ -272,13 +278,9 @@ The loading of immediate number in *`LoongArch`* is very cumbersome, and pseudo |=========================== *Usage :* + [source] ---- -li.w $r23, 0x76543210 # $r23 = 0x0000000076543210 -li.w: - lu12i.w $r23, 0x76543 # $r23 = 0x0000000076543000 - ori $r23, $r23, 0x210 # $r23 = 0x0000000076543210 - li.d $r23, 0xfedcba9876543210 # $r23 = 0xfedcba9876543210 li.d: lu12i.w $r23, 0x76543 # $r23 = 0x0000000076543000 @@ -287,6 +289,14 @@ li.d: lu52i.d $r23, $r23, 0xfed # $r23 = 0xfedcba9876543210 ---- +[source] +---- +li.w $r23, 0x76543210 # $r23 = 0x0000000076543210 +li.w: + lu12i.w $r23, 0x76543 # $r23 = 0x0000000076543000 + ori $r23, $r23, 0x210 # $r23 = 0x0000000076543210 +---- + [NOTE] ===== For more information, refer to the *`LoongArch Architecture manual:2.2.1.4`* . @@ -376,7 +386,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.5`* . <.^|*`$rd`* = (*unsigned*(*`$rj`*) `*<*` *unsigned*(`*Sign*`*Extend*(*`si12`*, GRLEN) ) ) ? `*1*` : `*0*` |=========================== -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] *Usage :* [source] @@ -432,7 +442,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.6`* . <.^|*`$rd`*[63:0] = {(*PC* `*+*` `*Sign*`*Extend* ({*`si20`*, 12'b0}, GRLEN) )[GRLEN-1:12], 12'b0} |=========================== -* *`si20`* : 20 bit immediate, Signed value range(*`integer`*) : [*`-524288`, `524287`*] or [*`-0x80000`, `0x7ffff`*] +* *`si20`* : 20-bit immediate, signed value range(*`integer`*) : [*`-524288`, `524287`*] or [*`-0x80000`, `0x7ffff`*] ** The input *`si20`* is the value *`before`* the *`offset operation`*. @@ -443,10 +453,7 @@ pcaddi $r24, 0x0000f # PC = 120000ba0; $r24 = 120000bdc # PC = 0x120000ba0, si20 = 0xf # 0xf = 0b00000000000000001111 -> 0b1111 -> 0b111100 -> 0x3c # $r24 = 0x120000ba0 + 0x3c = 0x120000bdc ----- -[source] ----- pcaddu12i $r24, 0x0000f # PC = 120000bb8; $r24 = 12000fbb8 # PC = 0x120000bb8, si20 = 0xf # 0xf = 0b00000000000000001111 -> 0b1111 -> 0b1111000000000000 -> 0xf000 @@ -461,6 +468,10 @@ pcalau12i $r24, 0x0000f # PC = 120000be8; $r24 = 12000f000 # PC = 0x120000be8, si20 = 0xf # 0xf = 0b00000000000000001111 -> 0b1111 -> 0b1111000000000000 -> 0xf000 # temp = 0x120000be8 + 0xf000 = 0x12000fbe8 +---- + +[source] +---- # $r24 = {temp[63:12], 12'b0} = 0x12000f000 # $r24 - PC = 0xe418 ---- @@ -584,7 +595,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.8`* . <.^|*`$rd`*[63:0] = (*`$rj`*[63:0]) `*^*` (`*Zero*`*Extend* (*`ui12`*, GRLEN)) |=========================== -* *`ui12`* : 12 bit immediate, Unsigned value range(*`integer`*) : [*`0`, `4095`*] or [*`0x000`, `0xfff`*] +* *`ui12`* : 12-bit immediate, unsigned value range(*`integer`*) : [*`0`, `4095`*] or [*`0x000`, `0xfff`*] *Usage :* [source] @@ -687,7 +698,7 @@ mulh.du $r25, $r26, $r27 # $r25 = 0x0000000000000007 * *Explanation :* -** The signed operation result of *`$r26`* multiplied by *`$r27`* is *`0xfffff88000000`*, and the unsigned operation result is *`0x00000078000000`*. Because the operation results of *`$23`*, *`$24`*, and *`$25`* are all stored in registers after signed extend, only *`31 bit`* to *`0 bit`* are taken when viewing the operation results. +** The signed result of multiplying *`$r26`* by *`$r27`* is *`0xfffff88000000`*, while the unsigned result is *`0x00000078000000`*. Because the operation results of *`$23`*, *`$24`*, and *`$25`* are all stored in registers after signed extend, only bits *`31`* to *`0`* are taken when viewing the operation results. [NOTE] ===== @@ -739,7 +750,6 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.1.11`* . ---- li.d $r26, 0x000000000000000f # $r26 = 0x000000000000000f li.d $r27, 0xffffffff80000000 # $r27 = 0xffffffff80000000 - mulw.d.w $r23, $r26, $r27 # $r23 = 0xfffffff880000000 mulw.d.wu $r24, $r26, $r27 # $r24 = 0x0000000780000000 ---- diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.10-Other_Miscellaneous_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.10-Other_Miscellaneous_Instructions.adoc index baa1f10..3a72e4f 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.10-Other_Miscellaneous_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.10-Other_Miscellaneous_Instructions.adoc @@ -1,6 +1,6 @@ ===== *8.1.1.10 Other Miscellaneous Instructions* -The information carried in the *`code`* field in the instruction *`code`* can be used as a parameter passed by the exception handling routine. +The information carried in the *`code`* field of the instruction *`code`* can be used as a parameter passed by the exception handling routine. ====== *8.1.1.10.1 `SYSCALL`* @@ -156,7 +156,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.10.4`* . *Description :* -*`cpucfg`* : When using the *`CPUCFG`* instruction, the source operand register *`rj`* stores the number of the configuration information word to be accessed, and the configuration information word information read after the instruction is executed is written into the general register *`rd`*. In *LA64*, each configuration information word is 32 bits, which is written into the result register after the sign extension. +*`cpucfg`* : When using the *`CPUCFG`* instruction, the source operand register *`rj`* stores the number of the configuration information word to be accessed, and the configuration information word information read after executing the instruction is written into the general register *`rd`*. In *LA64*, each configuration information word is 32 bits, which is written into the result register after sign extension. [NOTE] ===== diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.2-Bit-shift_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.2-Bit-shift_Instructions.adoc index 74e232a..7c19043 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.2-Bit-shift_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.2-Bit-shift_Instructions.adoc @@ -6,15 +6,15 @@ |=========================== <.^|*`SLL`* ^.^|*:* -<.^|Shift data logic left. +<.^|Shift data left logically. <.^|*`SRL`* ^.^|*:* -<.^|Shift data logic right. +<.^|Shift data right logically. <.^|*`SRA`* ^.^|*:* -<.^|Arithmetic shift of data to the right. +<.^|Arithmetic shift data to the right. <.^|*`ROTR`* ^.^|*:* @@ -99,13 +99,12 @@ srl.w $r25, $r23, $r24 # $r25 = 0x000000003c000003 sra.w $r25, $r23, $r24 # $r25 = 0xfffffffffc000003 # $r23 = 0xf000000e = 0b11110000000000000000000000001110 # $r25 = SignExtend({2'$r23[31], $r23[31:2]} , GRLEN) +# {2'$r23[31], $r23[31:2]} = 0b11111100000000000000000000000011 = 0xfc000003 +# $r25 = 0xfffffffffc000003 ---- [source] ---- -# {2'$r23[31], $r23[31:2]} = 0b11111100000000000000000000000011 = 0xfc000003 -# $r25 = 0xfffffffffc000003 - rotr.w $r25, $r23, $r24 # $r25 = 0xffffffffbc000003 # $r23 = 0xf000000e = 0b11110000000000000000000000001110 # $r25 = SignExtend({$r23[1:0], $r23[31:2]} , GRLEN) @@ -173,9 +172,9 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.2.1`* . <.^|} , GRLEN) |=========================== -Consider *`ui5`* as shift amount(*`SA`* is unsigned value range(*`integer`*) : [*`0` , `31`*]), which is the offset. +Consider *`ui5`* as the shift amount(*`SA`* is an unsigned value in the range(*`integer`*) : [*`0` , `31`*]), which serves as the offset. -* *`ui5`* : 5 bit immediate, Unsigned value range(*`integer`*) : [*`0`, `31`*] or [*`0x0`, `0x1f`*] +* *`ui5`* : 5-bit immediate, unsigned value range(*`integer`*) : [*`0`, `31`*] or [*`0x0`, `0x1f`*] *Usage :* [source] @@ -192,16 +191,16 @@ srli.w $r25, $r23, 2 # $r25 = 0x000000003c000003 # $r23 = 0xf000000e = 0b11110000000000000000000000001110 # $r25 = SignExtend({2'b0, $r23[31:2]} , GRLEN) # {2'b0, $r23[31:2]} = 0b00111100000000000000000000000011 = 0x3c000003 ----- - -[source] ----- # $r25 = 0x000000003c000003 srai.w $r25, $r23, 2 # $r25 = 0xfffffffffc000003 # $r23 = 0xf000000e = 0b11110000000000000000000000001110 # $r25 = SignExtend({2'$r23[31], $r23[31:2]} , GRLEN) # {2'$r23[31], $r23[31:2]} = 0b11111100000000000000000000000011 = 0xfc000003 +---- + +[source] +---- # $r25 = 0xfffffffffc000003 rotri.w $r25, $r23, 2 # $r25 = 0xffffffffbc000003 @@ -271,7 +270,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.2.2`* . <.^|} |=========================== -Consider *`$rk`*[5:0] as shift amount(*`SA`* is unsigned value range(*`integer`*) : [*`0` , `63`*]), which is the offset. +Consider *`$rk`*[5:0] as the shift amount(*`SA`* is an unsigned value in the range(*`integer`*) : [*`0` , `63`*]), which serves as the offset. *Usage :* @@ -285,10 +284,7 @@ sll.d $r25, $r23, $r24 # $r25 = 0xc000000000000038 # $r25 = {$r23[63-2:0], 2'b0} # $r25 = 0b1100000000000000000000000000000000000000000000000000000000111000 # $r25 = 0x0xc000000000000038 ----- -[source] ----- srl.d $r25, $r23, $r24 # $r25 = 0x3c00000000000003 # $r23 = 0b1111000000000000000000000000000000000000000000000000000000001110 # $r25 = {2'b0, $r23[63:2]} @@ -298,6 +294,10 @@ srl.d $r25, $r23, $r24 # $r25 = 0x3c00000000000003 sra.d $r25, $r23, $r24 # $r25 = 0xfc00000000000003 # $r23 = 0b1111000000000000000000000000000000000000000000000000000000001110 # $r25 = {2'$r23[63], $r23[63:2]} +---- + +[source] +---- # $r25 = 0b1111110000000000000000000000000000000000000000000000000000000011 # $r25 = 0x0xfc00000000000003 @@ -368,9 +368,9 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.2.3`* . <.^|} |=========================== -Consider *`ui6`* as shift amount(*`SA`* is unsigned value range(*`integer`*) : [*`0` , `63`*]), which is the offset. +Consider *`ui6`* as the shift amount(*`SA`* is an unsigned value in the range(*`integer`*) : [*`0` , `63`*]), which serves as the offset. -* *`ui6`* : 6 bit immediate, Unsigned value range(*`integer`*) : [*`0`, `63`*] or [*`0x0`, `0x3f`*] +* *`ui6`* : 6-bit immediate, unsigned value range(*`integer`*) : [*`0`, `63`*] or [*`0x0`, `0x3f`*] *Usage :* [source] @@ -378,10 +378,6 @@ Consider *`ui6`* as shift amount(*`SA`* is unsigned value range(*`integer`*) : [ li.d $r23, 0xf00000000000000e # $r23 = 0xf00000000000000e sll.d $r25, $r23, 2 # $r25 = 0xc000000000000038 ----- - -[source] ----- # $r23 = 0b1111000000000000000000000000000000000000000000000000000000001110 # $r25 = {$r23[63-2:0], 2'b0} # $r25 = 0b1100000000000000000000000000000000000000000000000000000000111000 @@ -392,7 +388,10 @@ srl.d $r25, $r23, 2 # $r25 = 0x3c00000000000003 # $r25 = {2'b0, $r23[63:2]} # $r25 = 0b0011110000000000000000000000000000000000000000000000000000000011 # $r25 = 0x0x3c00000000000003 +---- +[source] +---- sra.d $r25, $r23, 2 # $r25 = 0xfc00000000000003 # $r23 = 0b1111000000000000000000000000000000000000000000000000000000001110 # $r25 = {2'$r23[63], $r23[63:2]} diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.3-Bit-manipulation_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.3-Bit-manipulation_Instructions.adoc index ee0af79..e547803 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.3-Bit-manipulation_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.3-Bit-manipulation_Instructions.adoc @@ -48,15 +48,15 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.1`* . ====== *8.1.1.3.2 `CL{O/Z}.{W/D}`, `CT{O/Z}.{W/D}`* -This section involves four functions, namely CLO, CLZ, CTO, and CTZ. +This section involves four functions: CLO, CLZ, CTO, and CTZ. -* The `*CLO*` function performs the operation that for the data of bit [63/31:0] in the general register rj, the number of continuous bits 1 is measured from bit 63/31 to bit 0, and the result is written into the general register rd. +* The `*CLO*` function performs the operation that for the data of bit [63/31:0] in the general register *`rj`*, the number of continuous bits 1 is measured from bit 63/31 to bit 0, and the result is written into the general register *`rd`*. -* The `*CLZ*` function performs the operation that for the data of bit [63/31:0] in the general register rj, the number of continuous bits 0 is measured from bit 63/31 to bit 0, and the result is written into the general register rd. +* The `*CLZ*` function performs the operation that for the data of bit [63/31:0] in the general register *`rj`*, the number of continuous bits 0 is measured from bit 63/31 to bit 0, and the result is written into the general register *`rd`*. -* The `*CTO*` function performs the operation that for the data of bit [63/31:0] in the general register rj, the number of continuous bits 1 is measured from bit 0 to bit 63/31, and the result is written into the general register rd. +* The `*CTO*` function performs the operation that for the data of bit [63/31:0] in the general register *`rj`*, the number of continuous bits 1 is measured from bit 0 to bit 63/31, and the result is written into the general register *`rd`*. -* The `*CTZ*` function performs the operation that for the data of bit [63/31:0] in the general register rj, the number of continuous bits 0 is measured from bit 0 to bit 63/31, and the result is written into the general register rd. +* The `*CTZ*` function performs the operation that for the data of bit [63/31:0] in the general register *`rj`*, the number of continuous bits 0 is measured from bit 0 to bit 63/31, and the result is written into the general register *`rd`*. *Syntax:* @@ -135,9 +135,9 @@ clo.d $r25, $r23 # $r25 = 12 * *Explanation:* -** Calculate the number of consecutive bit 1 from bit 31 to bit 0. The operands involved in the calculation are *`0xf00fffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 4. +** Calculate the number of consecutive bits set to 1 from bit 31 to bit 0. The operand involved in the calculation is *`0xf00fffff`*, and the count stops when the first bit 0 occurs. So the result obtained from running the instruction is 4. -** Calculate the number of consecutive bit 1 from bit 63 to bit 0. The operands involved in the calculation are *`0xfff00000f00fffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 12. +** Calculate the number of consecutive bits set to 1 from bit 63 to bit 0. The operand involved in the calculation is *`0xfff00000f00fffff`*, and the count stops when the first bit 0 occurs. So the result obtained from running the instruction is 12. [source] ---- @@ -148,9 +148,9 @@ clz.d $r25, $r23 # $r25 = 12 * *Explanation:* -** Calculate the number of consecutive bit 0 from bit 31 to bit 0. The operands involved in the calculation are *`0x0000ffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 16. +** Calculate the number of consecutive bits set to 0 from bit 31 to bit 0. The operand involved in the calculation is *`0x0000ffff`*, and the count stops when the first bit 1 occurs. So the result obtained from running the instruction is 16. -** Calculate the number of consecutive bit 0 from bit 63 to bit 0. The operands involved in the calculation are *`0x000fffff0000ffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 12. +** Calculate the number of consecutive bits set to 0 from bit 63 to bit 0. The operand involved in the calculation is *`0x000fffff0000ffff`*, and the count stops when the first bit 1 occurs. So the result obtained from running the instruction is 12. [source] ---- @@ -161,9 +161,9 @@ cto.d $r25, $r23 # $r25 = 52 * *Explanation:* -** Calculate the number of consecutive bit 1 from bit 0 to bit 31. The operands involved in the calculation are *`0xffffffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 32. +** Calculate the number of consecutive bits set to 1 from bit 0 to bit 31. The operand involved in the calculation is *`0xffffffff`*, and the count stops when the first bit 0 occurs. So the result obtained from running the instruction is 32. -** Calculate the number of consecutive bit 1 from bit 0 to bit 63. The operands involved in the calculation are *`0x000fffffffffffff`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 52. +** Calculate the number of consecutive bits set to 1 from bit 0 to bit 63. The operand involved in the calculation is *`0x000fffffffffffff`*, and the count stops when the first bit 0 occurs. So the result obtained from running the instruction is 52. [source] ---- @@ -174,9 +174,9 @@ ctz.d $r25, $r23 # $r25 = 52 * *Explanation:* -** Calculate the number of consecutive bit 0 from bit 0 to bit 31. The operands involved in the calculation are *`0x00000000`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 32. +** Calculate the number of consecutive bits set to 0 from bit 0 to bit 31. The operand involved in the calculation is *`0x00000000`*, and the count stops when the first bit 1 occurs. So the result obtained from running the instruction is 32. -** Calculate the number of consecutive bit 0 from bit 0 to bit 63. The operands involved in the calculation are *`0xfff0000000000000`*, and stop when the first bit 0 occurs. So the result obtained by running the instruction is 52. +** Calculate the number of consecutive bits set to 0 from bit 0 to bit 63. The operand involved in the calculation is *`0xfff0000000000000`*, and the count stops when the first bit 1 occurs. So the result obtained from running the instruction is 52. [NOTE] ===== @@ -232,7 +232,12 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.2`* . ---- li.d $r23, 0x0000000001230000 # $r23 = 0x0000000001230000 li.d $r24, 0x0000000000004567 # $r24 = 0x0000000000004567 +---- + +[source] +---- bytepick.w $r25, $r23, $r24, sa2 # $r25 = 0x0000000045670123 + li.d $r23, 0x0123456700000000 # $r23 = 0x0123456700000000 li.d $r24, 0x0000000089abcdef # $r24 = 0x0000000089abcdef bytepick.d $r25, $r23, $r24, sa3 # $r25 = 0x89abcdef01234567 @@ -310,21 +315,21 @@ revb.d $r25, $r23 # $r25 = 0x1032547698badcfe * *Explanation:* -** Function description of the *`revb`* series instructions: Reverse the byte data within a specified range, with different suffixes determining different ranges. +** Function description of the *`revb`* series instructions: Reverse the byte order within a specified range, with different suffixes indicating different ranges. -** *`revb.2h`* represents dividing the data into two halfwords, and reversing the bytes in each of the two halfwords. When using the *`revb.h`* instruction to process *`0xfedcba9876543210`*, only data between bit 31 and bit 0 will be processed. *`0x76543210`* will be divided into two halfwords, namely *`0x7654`* and *`0x3210`*, and the bytes in the two will be arranged in reverse to obtain *`0x5476`* and *`0x1032`*. The final result is *`0x0000000054761032`*. +** *`revb.2h`* divides the data into two halfwords and reverses the bytes in each of the two halfwords. For example, when using the *`revb.h`* instruction to process *`0xfedcba9876543210`*, only the data between bit 31 and bit 0 will be processed. The lower 32 bits, *`0x76543210`*, will be divided into two halfwords: *`0x7654`* and *`0x3210`*. The bytes in these halfwords are then reversed to obtain *`0x5476`* and *`0x1032`*. The final result is *`0x0000000054761032`*. *** *`0xfedcba98 7654 3210`* -> *`revb`*(*`7654`, `3210`*) -> *`0x0000000054761032`* -** *`revb.4h`* means dividing the data into four halfwords and arranging the bytes in reverse order in each of the two halfwords. +** *`revb.4h`* divides the data into four halfwords and reverses the bytes in each of the four halfwords. *** *`0xfedc ba98 7654 3210`* -> *`revb`*(*`fedc`, `ba98`, `7654`, `3210`*) -> *`0xdcfe98ba54761032`* -** *`revb.2w`* means dividing the data into two words and arranging the bytes in reverse in each word. +** *`revb.2w`* divides the data into two words and reverses the bytes in each word. *** *`0xfedcba98 76543210`* -> *`revb`*(*`fedcba98`, `76543210`*) -> *`0x98badcfe10325476`* -** *`revb.d`* represents the reverse arrangement of bytes in the entire doubleword data. +** *`revb.d`* reverses the byte order of the entire doubleword data. *** *`0xfedcba9876543210`* -> *`revb`*(*`fedcba9876543210`*) -> *`0x1032547698badcfe`* @@ -426,7 +431,7 @@ bitrev.8b $r25, $r23 # $r25 = 0x7f3b5d196e2a4c08 ** *`bitrev.4b`* -*** Divide bit 31 to bit 0 into 4 bytes to perform a bitwise reverse order operation. +*** Divide the bits from 31 to 0 into 4 bytes and perform a bitwise reverse order operation. *** *`0x10`* -> *`0b00010000`* -> *bitrev*(*`0b00010000`*) -> *`0b00001000`* -> *`0x08`* @@ -440,7 +445,7 @@ bitrev.8b $r25, $r23 # $r25 = 0x7f3b5d196e2a4c08 ** *`bitrev.8b`* -*** Divide bit 63 to bit 0 into 8 bytes to perform a bitwise reverse order operation. +*** Divide the bits from 63 to 0 into 8 bytes and perform a bitwise reverse order operation. *** *`0x10`* -> *`0b00010000`* -> *bitrev*(*`0b00010000`*) -> *`0b00001000`* -> *`0x08`* @@ -576,7 +581,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.7`* . <.^|*`$rd`*[63:0] = `*Sign*`*Extend* ({*`$rd`*[31: *`msbw`*+1], *`$rj`*[*`msbw`*-*`lsbw`*:0], *`$rd`*[*`lsbw`*-1: 0]}, GRLEN) |=========================== -* *`msbw`*, *`lsbw`* : Unsigned value range(*`integer`*) : *31* > *`msbw`* > *`lsbw`* > *0* +* *`msbw`*, *`lsbw`* : Unsigned value range(*`integer`*) : *31* >= *`msbw`* >= *`lsbw`* >= *0* [grid=none] [frame=none] @@ -587,7 +592,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.7`* . <.^|*`$rd`*[63:0] = {*`$rd`*[63: *`msbd`*+1], *`$rj`*[*`msbd`*-*`lsbd`*:0], *`$rd`*[*`lsbd`*-1: 0]} |=========================== -* *`msbd`*, *`lsbd`* : Unsigned value range(*`integer`*) : *63* > *`msbd`* > *`lsbd`* > *0* +* *`msbd`*, *`lsbd`* : Unsigned value range(*`integer`*) : *63* >= *`msbd`* >= *`lsbd`* >= *0* *Usage :* [source] @@ -656,7 +661,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.8`* . <.^|*`$rd`*[63:0] = `*Sign*`*Extend* ( `*Zero*`*Extend* (*`$rj`*[*`msbw`* : *`lsbw`*], 32), GRLEN) |=========================== -* *`msbw`*, *`lsbw`* : Unsigned value range(*`integer`*) : *31* > *`msbw`* > *`lsbw`* > *0* +* *`msbw`*, *`lsbw`* : Unsigned value range(*`integer`*) : *31* >= *`msbw`* >= *`lsbw`* >= *0* [grid=none] [frame=none] @@ -667,7 +672,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.3.8`* . <.^|*`$rd`*[63:0] = `*Zero*`*Extend* (*`$rj`*[*`msbd`* : *`lsbd`*], 64) |=========================== -* *`msbd`*, *`lsbd`* : Unsigned value range(*`integer`*) : *63* > *`msbd`* > *`lsbd`* > *0* +* *`msbd`*, *`lsbd`* : Unsigned value range(*`integer`*) : *63* >= *`msbd`* >= *`lsbd`* >= *0* *Usage :* [source] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.4-Branch_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.4-Branch_Instructions.adoc index 011073b..cf7db57 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.4-Branch_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.4-Branch_Instructions.adoc @@ -180,10 +180,6 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.4.1`* . .L0 li.d $r23, 0x0 beqz $r23, .L2 ----- - -[source] ----- .L1 ... # When the value of $r23 is not 0, no jump. .L2 diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.5-Common_Memory_Access_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.5-Common_Memory_Access_Instructions.adoc index 4cc71a7..c8e5c04 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.5-Common_Memory_Access_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.5-Common_Memory_Access_Instructions.adoc @@ -63,7 +63,7 @@ <.^|*`$rd`*[63:0] = `*MemoryLoad*` (*`$rj`* `*+*` `*Sign*`*Extend* (*`si12`*, GRLEN), [63:0]) |=========================== -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] *Usage :* @@ -127,7 +127,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.5.1`* . <.^|`*MemoryStore*` ( *`$rd`*[63:0], ( *`$rj`* `*+*` `*Sign*`*Extend* (*`si12`*, GRLEN) ), [63:0] ) |=========================== -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] *Usage :* @@ -209,6 +209,10 @@ li.w $r24, -40 # $r24 = -40 # memory[$r22 - $r24] = 0x0123456789abcdef ldx.b $r23, $r22, $r24 # $r23 = 0xffffffffffffffef +---- + +[source] +---- ldx.bu $r23, $r22, $r24 # $r23 = 0x00000000000000ef ldx.h $r23, $r22, $r24 # $r23 = 0xffffffffffffcdef ldx.hu $r23, $r22, $r24 # $r23 = 0x000000000000cdef @@ -394,6 +398,8 @@ stptr.d $r23, $r22, -40 # memory[$r22 - 40] = 0xfedcba9876543210 For more information, refer to the *`LoongArch Architecture manual:2.2.5.3`* . ===== +<<< + ====== *8.1.1.5.6 `PRELD`, `PRELDX`* *Syntax:* @@ -423,15 +429,15 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.5.3`* . *`preld`* : -* The processor learns from the hint in the *`PRELD`* instruction what type will be acquired and which level of *`Cache`* the data to be taken back fill in, *`hint`* has 32 optional values (0 to 31), 0 represents load to level 1 *`Cache`*, and 8 represents store to level 1 *`Cache`*. The remaining *`hint`* values are not defined and are processed for nop instructions when the processor executes. +* The processor uses the hint in the *`PRELD`* instruction to determine the type of operation and which level of *`Cache`* to fill the data from. The *`hint`* has 32 optional values (0 to 31), where 0 represents a load to level 1 *`Cache`*, and 8 represents a store to level 1 *`Cache`*. The remaining *`hint`* values are not defined and are processed for nop instructions when the processor executes. -* *`si12`* : 12 bit immediate, Signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] +* *`si12`* : 12-bit immediate, signed value range(*`integer`*) : [*`-2048`, `2047`*] or [*`-0x800`, `0x7ff`*] *`preldx`* : -* The *`PRELDX`* instruction continuously prefetches data from memory into the Cache according to the configuration parameters, and the continuously prefetched data is a *`block`* (*`block`*) of length *`block_size`* starting from the specified base *`address`* (*`base`*) with a number of (*`block_num`*) spacing stride. The *`base address`* is the sum of the [63:0] bits in the general register *`rj`* and the sign extension [15:0] bits in the general register *`rk`*. The [I16] bits in general register *`rk`* are the address sequence ascending and descending flag bits, with 0 indicating address ascending and 1 indicating address descending. The value of bits [25:20] in general register *`rk`* is *`block_size`*, the basic unit of *`block_size`* is 16 bytes, so the maximum length of a single *`block`* is 1KB. The value of bits [39:32] in general register *`rk`* is *`block_num`*-*`1`*, so a single instruction can prefetch up to 256 *`blocks`*. The value of bits [59:44] in the block general register *`rk`* is treated as a signed number and defines the stride between adjacent blocks, the basic unit of stride is 1 byte. The value of bits [39:32] in *`rk`* is *`block.num`*-*`1`*, so a single instruction can prefetch up to 256 blocks. The value of bits [59:44] in general register *`rk`* is regarded as a signed number, which defines the corresponding The basic unit of stride and stride between adjacent blocks is 1 byte. +* The *`PRELDX`* instruction continuously prefetches data from memory into the cache according to the configuration parameters. The prefetch operation retrieves a *`block`* (*`block`*) of data, with a length of *`block_size`*, starting from a specified base *`address`* (*`base`*) and with a spacing stride defined by *`block_num`* . The *`base address`* is the sum of the [63:0] bits in the general register *`rj`* and the sign extension [15:0] bits in the general register *`rk`*. The [I16] bits in general register *`rk`* are the address sequence ascending and descending flag bits, where 0 indicates address ascending and 1 indicates address descending. The value of bits [25:20] in general register *`rk`* is *`block_size`*, with a basic unit of *`block_size`* is 16 bytes, so the maximum length of a single *`block`* is 1KB. The value of bits [39:32] in general register *`rk`* is *`block_num`*-*`1`*, so a single instruction can prefetch up to 256 *`blocks`*. The value of bits [59:44] in the block general register *`rk`* is treated as a signed number and defines the stride between adjacent blocks, with a basic unit of 1 byte. The value of bits [39:32] in *`rk`* is *`block.num`*-*`1`*, so a single instruction can prefetch up to 256 blocks. The value of bits [59:44] in general register *`rk`* is regarded as a signed number that defines the stride between adjacent blocks, with a basic unit of 1 byte. -* *`hint`* in the *`PRELDX`* instruction indicates the type of prefetch and the level of *`Cache`* into which the fetched data is to be filled. hint has 32 selectable values from 0 to 31. Currently, *`hint`*=*`0`* is defined as load prefetch to level 1 data *`Cache`*, *`hint`*=*`2`* is defined as load prefetch to level 3 *`Cache`*, *`hint`*=*`8`* is defined as store prefetch to level 1 data *`Cache`*. The meaning of the rest of *`hint`* values is not defined yet, and the processor executes it as *`NOP`* instruction. +* The *`hint`* in the *`PRELDX`* instruction indicates the type of prefetch and the level of *`Cache`* into which the fetched data is to be filled. The *`hint`* has 32 selectable values from 0 to 31. Currently, *`hint`*=*`0`* is defined as a load prefetch to level 1 data *`Cache`*, *`hint`*=*`2`* is defined as a load prefetch to level 3 *`Cache`*, *`hint`*=*`8`* is defined as a store prefetch to level 1 data *`Cache`*. The meanings of the remaining *`hint`* values are not yet defined and the processor executes it as *`NOP`* instruction. [NOTE] ===== diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.7-Atomic_Memory_Access_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.7-Atomic_Memory_Access_Instructions.adoc index b0a799b..7847603 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.7-Atomic_Memory_Access_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.7-Atomic_Memory_Access_Instructions.adoc @@ -378,6 +378,8 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.7.2`* . ^.^|*`$rj`* |=========================== +<<< + *Description :* [grid=none] @@ -531,6 +533,10 @@ addi.w $r25, $r25, 0 # $r25 = 0xffffffff89abcdef sc.w $r25, $r12, 0 # memory[$r12 + 0] = 0x0123456789abcdef ll.d $r25, $r12, 0 # $r25 = 0x0123456789abcdef +---- + +[source] +---- addi.d $r25, $r25, 10 # $r25 = 0x0123456789abcdef sc.d $r25, $r12, 0 # memory[$r12 + 0] = 0x0123456789abcdef ---- @@ -627,6 +633,8 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.7.5`* . <.^|*`$rd`*[63:0] = *`MemoryStore`* (*`$rd`*[63:0], *`$rj`*, [63:0]) |=========================== +<<< + *Usage :* [source] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.8-Barrier_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.8-Barrier_Instructions.adoc index c1f89d4..eaa60de 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.8-Barrier_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.1-Base_Integer_Instruction/8.1.1.8-Barrier_Instructions.adoc @@ -18,11 +18,11 @@ *Description :* -The *`DBAR`* instruction is used to complete the barrier function between *`load`*/*`store`* memory access operations. The immediate *`hint`* it carries is used to indicate the synchronization object and synchronization degree of the barrier. +The *`DBAR`* instruction is used to complete the barrier function between *`load`*/*`store`* memory access operations. The immediate *`hint`* it carries indicates the synchronization object and the degree of synchronization for the barrier. -A *`hint`* value of *`0`* is mandatory by default, and it indicates a fully functional synchronization barrier. Only after all previous *`load`*/*`store`* access operations are completely executed, the *`DBAR 0`* instruction can be executed; and only after the execution of *`DBAR 0`* is completed, all subsequent *`load`*/*`store`* access operations can be executed. +A *`hint`* value of *`0`* is mandatory by default, indicating a fully functional synchronization barrier. Only after all previous *`load`*/*`store`* access operations are completely executed, the *`DBAR 0`* instruction can be executed; and only after the execution of *`DBAR 0`* is completed, all subsequent *`load`*/*`store`* access operations can be executed. -If there is no special function implementation, all other *`hint`* values must be executed according to *`hint`*=*`0`*. +If there is no special functionality implemented, all other *`hint`* values must be executed according to *`hint`*=*`0`*. [NOTE] ===== @@ -47,7 +47,7 @@ For more information, refer to the *`LoongArch Architecture manual:2.2.8.1`* . *Description :* -The *`IBAR`* instruction is used to complete the synchronization between the *`store`* operation and the instruction fetch operation within a single processor core. The immediate *`hint`* it carries is used to indicate the synchronization object and synchronization degree of the barrier. +The *`IBAR`* instruction is used to complete the synchronization between the *`store`* operation and the instruction fetch operation within a single processor core. The immediate *`hint`* it carries indicates the synchronization object and the degree of synchronization for the barrier. A *`hint`* value of *`0`* is mandatory by default. It can ensure that the instruction fetch after the *`IBAR 0`* instruction must be able to observe the execution effect of all *`store`* operations before the *`IBAR 0`* instruction. diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions.adoc index f589af6..a31239a 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions.adoc @@ -1,10 +1,10 @@ ==== *8.1.2 Base Floating-point Instruction* [.text-justify] -This chapter will introduce the floating-point instructions in the non privileged subset foundation of the LoongArch architecture. Functional definition of the Basic Floating-point Instruction in the LoongArch Architecture. +This chapter will introduce the floating-point instructions in the non-privileged subset foundation of the LoongArch architecture. It will define the functional aspects of the basic floating-point instructions in accordance with the *`IEEE 754-2008 standard`*. [.text-justify] -Comply with *`IEEE 754-2008 standard`*. The basic floating-point instruction cannot be implemented separately from the basic integer instruction. Both the basic integer instruction and the basic floating-point instruction need to be implemented simultaneously. Whether the implementation of basic floating-point instructions includes instructions for manipulating double precision floating-point numbers and doubleword integers is independent of whether the architecture is *`LA32`* or *`LA64`*. +The basic floating-point instruction cannot be implemented separately from the basic integer instruction. Both the basic integer instruction and the basic floating-point instruction need to be implemented simultaneously. Whether the implementation of basic floating-point instructions includes instructions for manipulating double-precision floating-point numbers and doubleword integers is independent of whether the architecture is *`LA32`* or *`LA64`*. include::8.1.2-Base_Floating-Point_Instructions/8.1.2.1-Floating-Point_Arithmetic_Operation_Instructions.adoc[] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.1-Floating-Point_Arithmetic_Operation_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.1-Floating-Point_Arithmetic_Operation_Instructions.adoc index dc7e2bc..5089c5d 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.1-Floating-Point_Arithmetic_Operation_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.1-Floating-Point_Arithmetic_Operation_Instructions.adoc @@ -237,9 +237,14 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.1`* . * The above four floating-point *`fusion multiply-add`* operations follow the specification of the *`fusedMultiplyAdd`*(x,y,z) operation in the *`IEEE 754-2008 standard`* . *Usage :* + [source] ---- fmadd.s $f23, $f24, $f25, $f26 # $f23 = $f24 × $f25 + $f26 +---- + +[source] +---- fmadd.d $f23, $f24, $f25, $f26 # $f23 = $f24 × $f25 + $f26 fmsub.s $f23, $f24, $f25, $f26 # $f23 = $f24 × $f25 - $f26 fmsub.d $f23, $f24, $f25, $f26 # $f23 = $f24 × $f25 - $f26 @@ -389,11 +394,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.4`* . ^.^|dest ^.^|src1 -^.^|*`fabs.s`*, *`fabs.d`* -^.^|*`$fd`* -^.^|*`$fj`* - -^.^|*`fneg.s`*, *`fneg.d`* +^.^|*`fabs.s`*, *`fabs.d`*, *`fneg.s`*, *`fneg.d`* ^.^|*`$fd`* ^.^|*`$fj`* |=========================== @@ -429,6 +430,10 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.4`* . [source] ---- fabs.s $f23, $f24 # $f23 = |$f24| +---- + +[source] +---- fneg.d $f23, $f24 # $f23 = -$f24 ---- @@ -518,6 +523,8 @@ frsqrt.d $f23, $f24 # $f23 = 1.0 / sqrt($f24) For more information, refer to the *`LoongArch Architecture manual:3.2.1.6`* . ===== +<<< + ====== *8.1.2.1.7 `F{SCALEB/LOGB/COPYSIGN}.{S/D}`* *Syntax:* @@ -619,6 +626,8 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.7`* . ^.^|*`$fj`* |=========================== +<<< + *Description :* [grid=none] @@ -643,7 +652,7 @@ fclass.s $f23, $f24 fclass.d $f23, $f24 ---- -This instruction determines the category of floating-point numbers in the floating-point register *`$fj`*, and the resulting judgment result consists of a total of 10 bits of information. The meaning of each bit is as follows: +This instruction determines the category of floating-point numbers in the floating-point register *`$fj`*, with the resulting judgment consisting of a total of 10 bits of information. The meaning of each bit is as follows: [options="header"] [cols="8,8,8,10,16,8,8,10,16,8"] @@ -713,7 +722,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.8`* . <.^|*`$fd`*[63:0] = FP64 *`reciprocal estimate`* (*`$fj`*[63:0]) |=========================== -* The *`FRECIPE.{S/D}`* instruction selects the single-precision or double-precision floating-point number in the floating-point register *`$fj`*, calculates the single-precision or double-precision floating-point number approximation obtained by dividing the floating-point number by 1.0, and writes the approximation to the floating-point register *`$fd`* . The relative error of the approximation is less than 2^-14^. When the input value is 2^N^, the output value is 2^-N^. The results when the inputs are QNaN, SNaN, ±∞, ±0, the conditions for generating floating-point exceptions, and the default results when floating-point exceptions are generated without triggering exceptions are the same as those of the *`FRECIPE.{S/D}`* instruction. +* The *`FRECIPE.{S/D}`* instruction selects the single-precision or double-precision floating-point number in the floating-point register *`$fj`*, calculates the approximation of the floating-point number obtained by dividing it by 1.0, and writes the approximation to the floating-point register *`$fd`* . The relative error of the approximation is less than 2^-14^. When the input value is 2^N^, the output value is 2^-N^. The results when the inputs are QNaN, SNaN, ±∞, ±0, the conditions for generating floating-point exceptions, and the default results when floating-point exceptions are generated without triggering exceptions are the same as those of the *`FRECIPE.{S/D}`* instruction. [grid=none] [frame=none] @@ -728,7 +737,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.1.8`* . <.^|*`$fd`*[63:0] = FP64 *`reciprocal squareroot estimate`* (*`$fj`*[63:0]) |=========================== -* The *`FRSQRTE.{S/D}`* instruction selects the single-precision or double-precision floating-point number in the floating-point register *`$fj`*, first extract the Square Root it, and then divides the approximate result by 1.0, and then writes the obtained single-precision or double-precision floating-point number into the floating-point register *`$fd`* . The relative error of the obtained approximation is less than 2^-14^. When the input value is 2^2N^, the output value is 2^-N^. The results when the inputs are QNaN, SNaN, ±∞, ±0, the conditions for generating floating-point exceptions, and the default results when floating-point exceptions are generated without triggered exceptions are the same as those of the *`FRSQRTE.{S/D}`* instruction. +* The *`FRSQRTE.{S/D}`* instruction selects the single-precision or double-precision floating-point number in the floating-point register *`$fj`*, first extracts its square root, divides the approximate result by 1.0, and then writes the obtained single-precision or double-precision floating-point number into the floating-point register *`$fd`* . The relative error of the obtained approximation is less than 2^-14^. When the input value is 2^2N^, the output value is 2^-N^. The results when the inputs are QNaN, SNaN, ±∞, ±0, the conditions for generating floating-point exceptions, and the default results when floating-point exceptions are generated without triggered exceptions are the same as those of the *`FRSQRTE.{S/D}`* instruction. *Usage :* [source] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.2-Floating-Point_Comparison_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.2-Floating-Point_Comparison_Instructions.adoc index f153ad4..b738e80 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.2-Floating-Point_Comparison_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.2-Floating-Point_Comparison_Instructions.adoc @@ -25,7 +25,7 @@ ^.^|*`$fk`* |=========================== -This is a floating-point comparison instruction, which stores the result of the comparison into the specified status code (CC). There are 22 types of cond for this instruction. These comparison conditions and judgment standards are listed in the following table . +This is a floating-point comparison instruction, which stores the result of the comparison into the specified status code (CC). There are 22 types of conditions (*`cond`*) for this instruction. These comparison conditions and judgment standards are listed in the following table . [options="header"] [cols="20,40,20,20"] @@ -146,6 +146,8 @@ This is a floating-point comparison instruction, which stores the result of the ^.^|*`Yes`* |=========================== +<<< + *Description :* [grid=none] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.3-Floating-Point_Conversion_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.3-Floating-Point_Conversion_Instructions.adoc index 9a3f397..ed53fb5 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.3-Floating-Point_Conversion_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.3-Floating-Point_Conversion_Instructions.adoc @@ -96,7 +96,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.3.1`* . <.^|*`$fd`*[63:0] = FP64 `*convertFromInt*` ( *`$fj`*[63:0], SINT64 ) |=========================== -* The *`FFINT{S/D}.{W/L}`* instruction selects the *`integer`*/*`long-integer`* fixed-point number in the floating-point register *`$fj`* and converts it into a *`single`*/*`double`* floating-point number, and the obtained *`single`*/*`double`* floating-point number is written to Floating-point register *`$fd`*. The floating-point *`format conversion`* operation follows the specifications of the *`convertFromInt`*(x) operation in the *`IEEE 754-2008 standard`* . +* The *`FFINT{S/D}.{W/L}`* instruction selects the *`integer`*/*`long-integer`* fixed-point number from the floating-point register *`$fj`* and converts it into a *`single`*/*`double`* floating-point number. The resulting *`single`*/*`double`* floating-point number is then written to floating-point register *`$fd`*. The floating-point *`format conversion`* operation follows the specifications of the *`convertFromInt`*(x) operation in the *`IEEE 754-2008 standard`* . [grid=none] [frame=none] @@ -119,7 +119,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.3.1`* . <.^|*`$fd`*[63:0] = FP64 `*convertTo*` Sint64 ( *`$fj`*[63:0], FCSR.RM ) |=========================== -* The *`FTINT{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number in the floating-point register *`$fj`* to be converted into an *`integer`*/*`long-integer`* fixed-point number, and the obtained *`integer`*/*`long-integer`* fixed-point number is written To the floating-point memory *`$fd`*. According to the different states in *`FCSR`*, the operations in the *`IEEE 754-2008 standard`* followed by this floating-point *`format conversion`* operation are shown in the following table. +* The *`FTINT{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number from the floating-point register *`$fj`* and converts it into an *`integer`*/*`long-integer`* fixed-point number. The resulting *`integer`*/*`long-integer`* fixed-point number is then written to the floating-point memory *`$fd`*. Depending on the different states in *`FCSR`*, the operations in the *`IEEE 754-2008 standard`* followed by this floating-point *`format conversion`* operation are shown in the following table. --- @@ -173,6 +173,10 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.3.1`* . case {rm} of: {2'd0}: return Sint64_convertToIntegerExactTiesToEven(x) {2'd1}: return Sint64_convertToIntegerExactTowardZero(x) +---- + +[source] +---- {2'd2}: return Sint64_convertToIntegerExactTowardPositive(x) {2'd3}: return Sint64_convertToIntegerExactTowardNegative(x) ---- @@ -260,7 +264,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.3.2`* . <.^|*`$fd`*[63:0] = Sint64 `*convertToIntegerExactTowardNegative*` (*`$fj`*[63:0]) |=========================== -* *`FTINTRM.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number in the floating-point register *`$fj`* and converts it to *`integer`*/*`long-integer`* fixed point number, and the resulting *`integer`*/*`long-integer`* fixed point number is written to the floating-point register *`$fd`*, using the "*`round to negative infinity`*" mode. +* *`FTINTRM.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number from the floating-point register *`$fj`* and converts it into *`integer`*/*`long-integer`* fixed point number. The resulting *`integer`*/*`long-integer`* fixed-point number is then written to the floating-point register *`$fd`*, using the "*`round to negative infinity`*" mode. *Usage :* [source] @@ -298,7 +302,7 @@ ftintrm.l.d $f26, $f25 # $f26 = -5 <.^|*`$fd`*[63:0] = Sint64 `*convertToIntegerExactTowardPositive*` (*`$fj`*[63:0]) |=========================== -* *`FTINTRP.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number in the floating-point register *`$fj`*, converts it to *`integer`*/*`long-integer`* fixed point number, and writes the *`integer`*/*`long-integer`* fixed point number into the floating-point register *`$fd`*, using the "*`rounding to positive infinity`*" method. +* *`FTINTRP.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number from the floating-point register *`$fj`* and converts it into *`integer`*/*`long-integer`* fixed-point number. It then writes the resulting *`integer`*/*`long-integer`* fixed-point number to the floating-point register *`$fd`*, using the "*`rounding to positive infinity`*" method. *Usage :* [source] @@ -336,7 +340,7 @@ ftintrp.l.d $f26, $f25 # $f26 = 5 <.^|*`$fd`*[63:0] = Sint64 `*convertToIntegerExactTowardZero*` (*`$fj`*[63:0]) |=========================== -* *`FTINTRZ.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number in floating-point register *`$fj`*, converts it to *`integer`*/*`long-integer`* fixed-point number, and writes the obtained *`integer`*/*`long-integer`* fixed-point number to floating-point register *`$fd`*, using the "*`rounding to zero`*" method. +* *`FTINTRZ.{W/L}.{S/D}`* instruction selects the *`single`*/*`double`* floating-point number from floating-point register *`$fj`* and converts it into *`integer`*/*`long-integer`* fixed-point number. It then writes the resulting *`integer`*/*`long-integer`* fixed-point number to the floating-point register *`$fd`*, using the "*`rounding to zero`*" method. *Usage :* [source] @@ -370,7 +374,7 @@ ftintrz.w.s $f26, $f24 # $f26 = -4 <.^|*`$fd`*[63:0] = Sint64 `*convertToIntegerExactTiesToEven*` (*`$fj`*[63:0]) |=========================== -* *`FTINTRNE.{W/L}{S/D}`* instruction selects the *`single`*/*`double`* floating-point number in floating-point register *`$fj`*, converts it to *`integer`*/*`long-integer`* fixed point number, and writes the obtained *`integer`*/*`long-integer`* fixed point number to floating-point register *`$fd`*, using the "*`rounding to the nearest even number`*" method. +* *`FTINTRNE.{W/L}{S/D}`* instruction selects the *`single`*/*`double`* floating-point number from floating-point register *`$fj`* and converts it into *`integer`*/*`long-integer`* fixed-point number. It then writes the resulting *`integer`*/*`long-integer`* fixed-point number to floating-point register *`$fd`*, using the "*`rounding to the nearest even number`*" method. *Usage :* [source] @@ -424,7 +428,7 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.3.3`* . |=========================== * The operations in *`IEEE 754-2008 standard`* for floating-point format -conversion operations are shown in the table below.. +conversion are shown in the table below.. [options="header"] [cols="5,6"] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.4-Floating-Point_Move_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.4-Floating-Point_Move_Instructions.adoc index 12761b4..1eaf341 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.4-Floating-Point_Move_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.4-Floating-Point_Move_Instructions.adoc @@ -33,7 +33,7 @@ <.^|*`$fd`*[63:0] = *`$fj`*[63:0] |=========================== -* *`FMOV{S/D}`* Write the value of floating-point register *`$fj`* in single/double precision floating-point format to floating-point register *`$fd`*. If the value of *`$fj`* is not in *`single`*/*`double`* floating-point format, the result is uncertain. The above instruction operations are non arithmetic and do not raise *`IEEE 754`* exceptions, nor do they modify the Cause and Flags fields of the floating-point control status register. +* *`FMOV{S/D}`* writes the value of floating-point register *`$fj`* in single/double precision floating-point format to floating-point register *`$fd`*. If the value of *`$fj`* is not in *`single`*/*`double`* floating-point format, the result is uncertain. The above instruction operations are non-arithmetic and do not raise *`IEEE 754`* exceptions, nor do they modify the Cause and Flags fields of the floating-point control status register. *Usage :* [source] @@ -80,7 +80,9 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.4.1`* . <.^|*`$fd`* = *`$fcc`*[*`ca`*] ? *`$fk`* : *`$fj`* |=========================== -* The *`FSEL`* instruction performs conditional assignment operations. When *`FSEL`* is executed, if the value of the condition flag register *`ca`* is equal to 0, the value of floating-point register *`$fj`* is written to *`$fd`*; otherwise, the value of floating-point register *`$fk`* is written to *`$fd`*. +* The *`FSEL`* instruction performs conditional assignment operations. When *`FSEL`* is executed, if the value of the condition flag register *`ca`* is equal to 0, the value from floating-point register *`$fj`* is written to *`$fd`*; otherwise, the value from floating-point register *`$fk`* is written to *`$fd`*. + +<<< *Usage :* [source] @@ -270,6 +272,8 @@ For more information, refer to the *`LoongArch Architecture manual:3.2.4.5`* . ^.^|*`$FCC`*[*`cj`*] |=========================== +<<< + *Description :* [grid=none] diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.6-Floating-Point_Common_Memory_Access_Instructions.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.6-Floating-Point_Common_Memory_Access_Instructions.adoc index 1974fa5..dd2bd5e 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.6-Floating-Point_Common_Memory_Access_Instructions.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions/8.1.2.6-Floating-Point_Common_Memory_Access_Instructions.adoc @@ -77,6 +77,8 @@ fst.d $f24, $r12, 0 # memory[$r12] = 0x400c000000000000 = 3. For more information, refer to the *`LoongArch Architecture manual:3.2.6.1`* . ===== +<<< + ====== *8.1.2.6.2 `FLDX.{S/D}`, `FSTX.{S/D}`* *Syntax:* diff --git a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction_Introduction.adoc b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction_Introduction.adoc index 2c0a9b5..baeb38d 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction_Introduction.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.1-Base_Instruction_Introduction.adoc @@ -1,7 +1,7 @@ === *8.1 Base Instruction Introduction* [.text-justify] -The basic part of the *`LoongArch`* architecture consists of two parts: the non privileged instruction set and the privileged instruction set. The non privileged instruction set defines commonly used integer and floating-point instructions, which can fully support the generation of efficient object code by existing mainstream compilation systems. +The basic part of the *`LoongArch`* architecture consists of two parts: the non-privileged instruction set and the privileged instruction set. The non-privileged instruction set defines commonly used integer and floating-point instructions, which can fully support the generation of efficient object code by existing mainstream compilation systems. <<< @@ -11,3 +11,4 @@ include::8.1-Base_Instruction/8.1.1-Base_Integer_Instruction.adoc[] include::8.1-Base_Instruction/8.1.2-Base_Floating-Point_Instructions.adoc[] + diff --git a/adoc/CHAPTER-8.Instruction_Set/8.Instruction_Set.adoc b/adoc/CHAPTER-8.Instruction_Set/8.Instruction_Set.adoc index 3fc8f3a..540dc6e 100644 --- a/adoc/CHAPTER-8.Instruction_Set/8.Instruction_Set.adoc +++ b/adoc/CHAPTER-8.Instruction_Set/8.Instruction_Set.adoc @@ -1,9 +1,9 @@ == *CHAPTER 8. Instruction Set* [.text-justify] -The *`LoongArch`* architecture is divided into two versions: 32-bit and 64-bit, respectively referred to as *`LA32`* architecture and *`LA64`* architecture. The *`LA64`* architecture is application level down binary compatible with the *`LA32`* architecture. The so-called "application level down binary compatibility" refers to the fact that the binaries of application software using the *`LA32`* architecture can directly run on machines compatible with the *`LA64`* architecture and obtain the same running results. On the other hand, it refers to the fact that this down binary compatibility is limited to application software. The architecture specification does not guarantee that the binary of system software (such as the operating system kernel) running on machines compatible with *`LA32`* architecture always obtains the same running result when running directly on machines compatible with *`LA64`* architecture. +The *`LoongArch`* architecture is divided into two versions: the 32-bit *`LA32`* architecture and the 64-bit *`LA64`* architecture. The *`LA64`* architecture is application-level downward binary compatible with the *`LA32`* architecture. This means that binaries of application software built for *`LA32`* can run directly run on machines compatible with the *`LA64`* architecture and produce the same running results. On the other hand, it refers to the fact that this downward binary compatibility is limited to application software. The architecture specification does not guarantee that binaries of system software (such as the operating system kernel) running on machines compatible with *`LA32`* architecture always yields the same running result when running directly on machines compatible with *`LA64`* architecture. -The hexadecimal representation of the integer range involved in this book must contain signed, for example, [-*`0x800`*, *`0x7ff`*] indicates that the range is [-*`2048`*, *`2047`*], where the minus sign of -*`0x800`* must exist. Otherwise, the assembler overflow error will occur. If it is necessary to not write signed to represent this range, the *`0x800`* and *`0x7ff`* should be signed extended to *`GRLEN`*, corresponding to [*`0xfffffff800`*, *`0x0000007ff`*] of *`LA32`* and [*`0xfffffffffff800`*, *`0x00000000007ff`*] of *`LA64`*. +The hexadecimal representation of the integer ranges involved in this book must include a sign. For example, [-*`0x800`*, *`0x7ff`*] indicates the the range [-*`2048`*, *`2047`*], where the minus sign for -*`0x800`* must exist. Otherwise, the assembler overflow error will occur. If you need to represent this range without a sign, *`0x800`* and *`0x7ff`* should be sign-extended to *`GRLEN`*, resulting in [*`0xfffffff800`*, *`0x0000007ff`*] for *`LA32`* and [*`0xfffffffffff800`*, *`0x00000000007ff`*] for *`LA64`*. include::8.1-Base_Instruction_Introduction.adoc[] diff --git a/adoc/CHAPTER-9.Pseudo_Instruction_Set/9.Pseudo_Instruction_Set.adoc b/adoc/CHAPTER-9.Pseudo_Instruction_Set/9.Pseudo_Instruction_Set.adoc index 1e8a478..1990f26 100644 --- a/adoc/CHAPTER-9.Pseudo_Instruction_Set/9.Pseudo_Instruction_Set.adoc +++ b/adoc/CHAPTER-9.Pseudo_Instruction_Set/9.Pseudo_Instruction_Set.adoc @@ -1,431 +1,1167 @@ -== *CHAPTER 9. Pseudo Instructions* +== *CHAPTER 9. Macro Instructions* [.text-justify] -The LoongArch assembler supports a number of pseudo-instructions that are translated into the appropriate combination of LoongArch instructions at assembly time. +The LoongArch assembler supports a number of pseudo-instructions that are translated into the appropriate combination of LoongArch instructions during assembly. + +=== *9.1 ALU Macro Instructions* + +==== *9.1.1 `move`* + +*Syntax:* + + opcode dest, src1 [options="header"] -[cols="30,35,35"] +[cols="80,10,10"] |=========================== -^.^|Pseudo Instruction -^.^|Machine Instruction -^.^|Meaning +^.^|opcode +^.^|dest +^.^|src1 -<.^|*`jr`* *`$rd`* -<.^|*`jirl`* *`$zero`*, *`$rd`*, *`0`* -<.^|Direct register jump +^.^|*`move`* +^.^|*`$rd`* +^.^|*`$rj`* +|=========================== -<.^|*`ret`* (*`jr`* *`$ra`*) -<.^|*`jirl`* *`$zero`*, *`$ra`*, *`0`* -<.^|Function return +*Description :* -<.^|*`bgt`* *`$rj`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`blt`* *`$rd`*, *`$rj`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rj`* > *`$rd`*)jump (*`si18`* \| *`symbol`*) +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +.2+^.<|*`move`* +.2+^.<|*:* +<.<|*`$rd`* *=* *`$rj`* +<.<|Assign the value of *`$rj`* to *`$rd`* +|=========================== -<.^|*`bgtu`* *`$rj`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`bltu`* *`$rd`*, *`$rj`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rj`* > *`$rd`*)jump (*`si18`* \| *`symbol`*) +*Usage :* -<.^|*`ble`* *`$rj`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`bge`* *`$rd`*, *`$rj`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rj`* < = *`$rd`*)jump (*`si18`* \| *`symbol`*) +[source] +---- +move $t0, $t1 +Machine Instruction --------------- +or $t0, $t1, $zero +---- -<.^|*`bleu`* *`$rj`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`bgeu`* *`$rd`*, *`$rj`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rj`* < = *`$rd`*)jump (*`si18`* \| *`symbol`*) +==== *9.1.2 `li.w/d`* -<.^|*`bltz`* *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`blt`* *`$rd`*, *`$zero`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rd`* < *`0`*)jump (*`si18`* \| *`symbol`*) +*Syntax:* -<.^|*`bgtz`* *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`blt`* *`$zero`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rd`* > *`0`*)jump (*`si18`* \| *`symbol`*) + opcode dest, src1 -<.^|*`blez`* *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`bge`* *`$zero`*, *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rd`* < = *`0`*)jump (*`si18`* \| *`symbol`*) +[options="header"] +[cols="80,10,10"] +|=========================== +^.^|opcode +^.^|dest +^.^|src1 -<.^|*`bgez`* *`$rd`*, (*`si18`* \| *`symbol`*) -<.^|*`bge`* *`$rd`*, *`$zero`*, (*`si18`* \| *`symbol`*) -<.^|if(*`$rd`* > = *`0`*)jump (*`si18`* \| *`symbol`*) +^.^|*`li.w`* +^.^|*`$rd`* +^.^|*`IMM32`* -<.^|*`move`* *`$rd`*, *`$rj`* -<.^|*`or`* *`$rd`*, *`$rj`*, *`$zero`* -<.^|Assign the value of *`$rj`* to *`$rd`* +^.^|*`li.d`* +^.^|*`$rd`* +^.^|*`IMM64`* |=========================== -[options="header"] -[cols="30,35,35"] +*Description :* + +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +.2+^.<|*`li.w`* +.2+^.<|*:* +<.<|*`$rd`* *=* *`IMM32`* +<.<|Load a *`IMM32`* to *`$rd`* + +.2+^.<|*`li.d`* +.2+^.<|*:* +<.<|*`$rd`* *=* *`IMM64`* +<.<|Load a *`IMM64`* to *`$rd`* |=========================== -^.^|Pseudo Instruction -^.^|Machine Instruction -^.^|Meaning -.2+<.^|*`li.w`* *`$rd`*, *`imm32`* +*Usage :* -<.^|*`lu12i.w`* *`$rd`*, *`si20`* +* *`li.w` :* -.2+<.^|Load a 32-bit immediate +[source] +---- +li.w $t0, 0x76543210 +Machine Instruction ------------------------------------------------------------------ +lu12i.w $t0, si20 // load IMM32[31:12] $t0 = 0x76543000 +ori $t0, $t0, si12 // load IMM32[11: 0] $t0 = 0x76543210 +---- -<.^|*`ori`* *`$rd`*, *`$rd`*, *`si12`* +* *`li.d` :* -.4+<.^|*`li.d`* *`$rd`*, *`imm64`* +[source] +---- +li.d $t0, 0xfedcba9876543210 +Machine Instruction ------------------------------------------------------------------ +lu12i.w $rd, si20 // load IMM64[31:12] $t0 = 0x0000000076543000 +ori $rd, $rd, si12 // load IMM64[11: 0] $t0 = 0x0000000076543210 +lu32i.d $rd, si20 // load IMM64[51:32] $t0 = 0x000cba9876543210 +lu52i.d $rd, $rd, si12 // load IMM64[63:52] $t0 = 0xfedcba9876543210 +---- -<.^|*`lu12i.w`* *`$rd`*, *`si20`* +=== *9.2 Jump Macro Instructions* -.4+<.^|Load a 64-bit immediate +==== *9.2.1 `jr`* -<.^|*`ori`* *`$rd`*, *`$rd`*, *`si12`* -<.^|*`lu32i.w`* *`$rd`*, *`si20`* -<.^|*`lu52i.w`* *`$rd`*, *`si12`* -|=========================== +*Syntax:* + + opcode src1 [options="header"] -[cols="40,10,50"] +[cols="90,10"] +|=========================== +^.^|opcode +^.^|src1 + +^.^|*`jr`* +^.^|*`$rd`* |=========================== -^.^|Macros Instruction -^.^|Feature -^.^|Machine Instructions -.8+<.^|*`la`* *`$rd`*, *`sym`* +*Description :* -.2+^.^|*`NORMAL`* +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +.2+^.<|*`jr`* +.2+^.<|*:* +<.<|jump to address(*`$rd`*) +<.<|Direct register jump +|=========================== -<.^|*`pcalau12i`* *`$rd`*, *`%got_pc_hi20`*(*`sym`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%got_pc_lo12`*(*`sym`*) +*Usage :* -.2+^.^|*`GTOPCR`* +[source] +---- +jirl $t4 +Machine Instruction ------------- +jirl $zero, $t4, 0 +---- -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym`*) -<.^|*`addi.d`* *`$rd`*, *`$rd`*, *`%pc_lo12`*(*`sym`*) +==== *9.2.2 `ret`* -.4+^.^|*`GTOABS`* -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%abs_lo12`*(*`sym`*) -<.^|*`lu32i.d`* *`$rd`*, *`%abs64_lo20`*(*`sym`*) -<.^|*`lu52i.d`* *`$rd`*, *`$rd`*, *`%abs64_hi12`*(*`sym`*) -|=========================== +*Syntax:* + + opcode [options="header"] -[cols="40,10,50"] |=========================== -^.^|Macros Instruction -^.^|Feature -^.^|Machine Instructions +^.^|opcode -.8+<.^|*`la.global`* *`$rd`*, *`sym_global`* +^.^|*`ret`* +|=========================== -.2+^.^|*`NORMAL`* +<<< -<.^|*`pcalau12i`* *`$rd`*, *`%got_pc_hi20`*(*`sym_global`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%got_pc_lo12`*(*`sym_global`*) +*Description :* -.2+^.^|*`GTOPCR`* +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +^.<|*`ret`* +^.<|*:* +<.<|Function return +|=========================== -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_global`*) -<.^|*`addi.d`* *`$rd`*, *`$rd`*, *`%pc_lo12`*(*`sym_global`*) +*Usage :* -.4+^.^|*`GTOABS`* -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym_global`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%abs_lo12`*(*`sym_global`*) -<.^|*`lu32i.d`* *`$rd`*, *`%abs64_lo20`*(*`sym_global`*) -<.^|*`lu52i.d`* *`$rd`*, *`$rd`*, *`%abs64_hi12`*(*`sym_global`*) -|=========================== +[source] +---- +ret +Machine Instruction ------------- +jirl $zero, $ra, 0 +---- + +==== *9.2.3 `call36`* + +*Syntax:* + + opcode src1 [options="header"] -[cols="40,10,50"] +[cols="90,10"] |=========================== -^.^|Macros Instruction -^.^|Feature -^.^|Machine Instructions +^.^|opcode +^.^|src1 -.14+<.^|*`la.global`* *`$rd`*, *`$rj`*, *`sym_global_large`* +^.^|*`call36`* +^.^|*`sym_call`* +|=========================== -.5+^.^|*`NORMAL`* +*Description :* -<.^|*`pcalau12i`* *`$rd`*, *`%got_pc_hi20`*(*`sym_global_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%got_pc_lo12`*(*`sym_global_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%got64_pc_lo20`*(*`sym_global_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%got64_pc_hi12`*(*`sym_global_large`*) -<.^|*`ldx.d`* *`$rd`*, *`$rd`*, *`$rj`* +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +^.<|*`call36`* +^.<|*:* +<.<|jump to *`sym_call`* +|=========================== -.5+^.^|*`GTOPCR`* +*Usage :* -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_global_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%pc_lo12`*(*`sym_global_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%pc64_lo20`*(*`sym_global_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%pc64_hi12`*(*`sym_global_large`*) -<.^|*`add.d`* *`$rd`*, *`$rd`*, *`$rj`* +[source] +---- +call36 sym_call +Machine Instruction ---------------------- +pcaddu18i $ra, %call36(sym_call) +jirl $ra, $ra, 0 +---- -.4+^.^|*`GTOABS`* +* sym_call only allows symbol names, not immediate values. -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym_global_large`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%abs_lo12`*(*`sym_global_large`*) -<.^|*`lu32i.d`* *`$rd`*, *`%abs64_lo20`*(*`sym_global_large`*) -<.^|*`lu52i.d`* *`$rd`*, *`$rd`*, *`%abs64_hi12`*(*`sym_global_large`*) -|=========================== +[NOTE] +==== +The addressing range of *`call36`* depends on the range of {*`si20`*,18b0} in *`pcaddu18i`*. For details, see the *`https://github.com/loongson/la-abi-specs/releases/tag/v2.30/la-abi.pdf[LoongArch abi manual]:8.3`* . +==== -*Feature* : +==== *9.2.4 `tail36`* -* *`GTOPCR`* : *`la-global-with-pcrel`* +*Syntax:* -* *`GTOABS`* : *`la-global-with-abs`* + opcode src1, src2 [options="header"] -[cols="40,10,50"] +[cols="80,10,10"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 + +^.^|*`tail36`* +^.^|*`$rd`* +^.^|*`sym_tail`* +|=========================== + +*Description :* + +[grid=none] +[frame=none] +[cols="85,20,895"] +|=========================== +^.<|*`tail36`* +^.<|*:* +<.<|jump to *`sym_tail`* |=========================== -^.^|Macros Instruction -^.^|Feature -^.^|Machine Instructions -.6+<.^|*`la.local`* *`$rd`*, *`sym_local`* +*Usage :* -.2+^.^|*`NORMAL`* +[source] +---- +tail36 $t1, sym_tail +Machine Instruction ---------------------- +pcaddu18i $t1, %call36(sym_tail) +jirl $t1, $t1, 0 +---- -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_local`*) -<.^|*`addi.d`* *`$rd`*, *`$rd`*, *`%pc_lo12`*(*`sym_local`*) +* sym_call only allows symbol names, not immediate values. -.4+^.^|*`LTOABS`* +[NOTE] +==== +The addressing range of *`tail36`* depends on the range of {*`si20`*,18b0} in *`pcaddu18i`*. For details, see the *`https://github.com/loongson/la-abi-specs/releases/tag/v2.30/la-abi.pdf[LoongArch abi manual]:8.3`* . +==== -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym_local`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%abs_lo12`*(*`sym_local`*) -<.^|*`lu32i.d`* *`$rd`*, *`%abs64_lo20`*(*`sym_local`*) -<.^|*`lu52i.d`* *`$rd`*, *`$rd`*, *`%abs64_hi12`*(*`sym_local`*) -|=========================== +=== *9.3 Branch Macro Instructions* + +==== *9.3.1 `bgt`, `ble`, `bgtu`, `bleu`* + +*Syntax:* + + opcode src1, src2, src3 [options="header"] -[cols="40,10,50"] +[cols="60,10,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 +^.^|src3 + +^.^|*`bgt`*, *`ble`*, *`bgtu`*, *`bleu`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`si18` \| `symbol`* |=========================== -^.^|Macros Instruction -^.^|Feature -^.^|Machine Instructions -.9+<.^|*`la.local`* *`$rd`*, *`$rj`*, *`sym_local_large`* +*Description :* -.5+^.^|*`NORMAL`* +[grid=none] +[frame=none] +[cols="55,20,40,150,50,150,535"] +|=========================== +<.^|*`bgt`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rj`*) +^.^|`*>*` +^.^|signed(*`$rd`*) +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`ble`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rj`*) +^.^|`*< =*` +^.^|signed(*`$rd`*) +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`bgtu`* +^.^|*:* +<.^|*if* ( +^.^|unsigned(*`$rj`*) +^.^|`*>*` +^.^|unsigned(*`$rd`*) +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`bleu`* +^.^|*:* +<.^|*if* ( +^.^|unsigned(*`$rj`*) +^.^|`*< =*` +^.^|unsigned(*`$rd`*) +<.^|) *jump* ( *`si18` `\|` `symbol`* ) +|=========================== -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_local`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%pc_lo12`*(*`sym_local`*) -<.^|*`lu32i.d`* *`$rj`*, *`%pc64_lo20`*(*`sym_local`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%pc64_hi12`*(*`sym_local`*) -<.^|*`add.d`* *`$rd`*, *`$rd`*, *`$rj`* +* *`si18`* : a 4-bytes aligned 18-bits signed immediate value in range : -.4+^.^|*`LTOABS`* +** [*`-131072`*, *`131068`*] or [*`-0x20000`*, *`0x1fffc`*] -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym_local`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%abs_lo12`*(*`sym_local`*) -<.^|*`lu32i.d`* *`$rd`*, *`%abs64_lo20`*(*`sym_local`*) -<.^|*`lu52i.d`* *`$rd`*, *`$rd`*, *`%abs64_hi12`*(*`sym_local`*) -|=========================== +* *`symbol`* : Tags in assembly for jump. -*Feature* : +*Usage :* -* *`LTOABS`* : *`la-local-with-abs`* +[source] +---- +bgt $rj, $rd, si18 or symbol +ble $rj, $rd, si18 or symbol +bgtu $rj, $rd, si18 or symbol +bleu $rj, $rd, si18 or symbol +Machine Instruction ------------------------ +blt $rd, $rj, si18 or symbol +bge $rd, $rj, si18 or symbol +bltu $rd, $rj, si18 or symbol +bgeu $rd, $rj, si18 or symbol +---- + +==== *9.3.2 `bltz`, `bgtz`, `blez`, `bgez`* + +*Syntax:* + + opcode src1, src2 [options="header"] -[cols="50,50"] +[cols="70,10,20"] |=========================== -^.^|Macros Instruction -^.^|Machine Instructions - -.4+<.^|*`la.abs`* *`$rd`*, *`sym_abs`* +^.^|opcode +^.^|src1 +^.^|src2 -<.^|*`lu12i.w`* *`$rd`*, *`%abs_hi20`*(*`sym_abs`*) -<.^|*`ori`* *`$rj`*, *`$zero`*, *`%abs_lo12`*(*`sym_abs`*) -<.^|*`lu32i.d`* *`$rj`*, *`%abs64_lo20`*(*`sym_abs`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%abs64_hi12`*(*`sym_abs`*) +^.^|*`bltz`*, *`bgtz`*, *`blez`*, *`bgez`* +^.^|*`$rd`* +^.^|*`si18` \| `symbol`* |=========================== -[options="header"] -[cols="50,50"] +*Description :* + +[grid=none] +[frame=none] +[cols="55,20,40,150,50,50,635"] +|=========================== +<.^|*`bltz`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rd`*) +^.^|`*>*` +^.^|*`0`* +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`bgtz`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rd`*) +^.^|`*<*` +^.^|*`0`* +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`blez`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rd`*) +^.^|`*< =*` +^.^|*`0`* +<.^|) *jump* ( *`si18` `\|` `symbol`* ) + +<.^|*`bgez`* +^.^|*:* +<.^|*if* ( +^.^|signed(*`$rd`*) +^.^|`*> =*` +^.^|*`0`* +<.^|) *jump* ( *`si18` `\|` `symbol`* ) |=========================== -^.^|Macros Instruction -^.^|Machine Instructions -.2+<.^|*`la.pcrel`* *`$rd`*, *`sym_pcrel`* +* *`si18`* : a 4-bytes aligned 18-bits signed immediate value in range : -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_pcrel`*) -<.^|*`addi.d`* *`$rd`*, *`$rd`*, *`%pc_lo12`*(*`sym_pcrel`*) +** [*`-131072`*, *`131068`*] or [*`-0x20000`*, *`0x1fffc`*] -.5+<.^|*`la.pcrel`* *`$rd`*, *`$rj`*, *`sym_pcrel_large`* +* *`symbol`* : Tags in assembly for jump. -<.^|*`pcalau12i`* *`$rd`*, *`%pc_hi20`*(*`sym_pcrel_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%pc_lo12`*(*`sym_pcrel_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%pc64_lo20`*(*`sym_pcrel_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%pc64_hi12`*(*`sym_pcrel_large`*) -<.^|*`add.d`* *`$rd`*, *`$rd`*, *`$rj`* -|=========================== +*Usage :* -[options="header"] -[cols="50,50"] -|=========================== -^.^|Macros Instruction -^.^|Machine Instructions +[source] +---- +bltz $rd, si18 or symbol +bgtz $rd, si18 or symbol +blez $rd, si18 or symbol +bgez $rd, si18 or symbol +---- -.2+<.^|*`la.got`* *`$rd`*, *`sym_got`* +[source] +---- +Machine Instruction -------------------------- +blt $rd, $zero, si18 or symbol +blt $zero, $rd, si18 or symbol +bge $zero, $rd, si18 or symbol +bge $rd, $zero, si18 or symbol +---- -<.^|*`pcalau12i`* *`$rd`*, *`%got_pc_hi20`*(*`sym_got`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%got_pc_lo12`*(*`sym_got`*) +=== *9.4 Load Address Macro Instructions* -.5+<.^|*`la.got`* *`$rd`*, *`$rj`*, *`sym_got_large`* +* Load the *`symbol address`* into a general register and package the relocation information. -<.^|*`pcalau12i`* *`$rd`*, *`%got_pc_hi20`*(*`sym_got_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%got_pc_lo12`*(*`sym_got_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%got64_pc_lo20`*(*`sym_got_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%got64_pc_hi12`*(*`sym_got_large`*) -<.^|*`ldx.d`* *`$rd`*, *`$rd`*, *`$rj`* -|=========================== +==== *9.4.1 `la`.{`local`/`global`}* + +*Syntax:* + + opcode src1, src2 [options="header"] -[cols="50,50"] +[cols="70,10,20"] |=========================== -^.^|Macros Instruction -^.^|Machine Instructions +^.^|opcode +^.^|src1 +^.^|src2 -.2+<.^|*`la.tls.le`* *`$rd`*, *`sym_le`* +^.^|*`la.local`* +^.^|*`$rd`* +^.^|*`sym_local`* -<.^|*`lu12i.w`* *`$rd`*, *`%le_hi20`*(*`sym_le`*) -<.^|*`ori`* *`$rd`*, *`$rd`*, *`%le_lo12`*(*`sym_le`*) +^.^|*`la`*, *`la.global`* +^.^|*`$rd`* +^.^|*`sym_global`* +|=========================== -.2+<.^|*`la.tls.ie`* *`$rd`*, *`sym_ie`* + opcode src1, src2, src3 -<.^|*`pcalau12i`* *`$rd`*, *`%ie_pc_hi20`*(*`sym_ie`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%ie_pc_lo12`*(*`sym_ie`*) +[options="header"] +[cols="60,10,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 +^.^|src3 + +^.^|*`la.local`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_local_large`* + +^.^|*`la.global`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_global_large`* +|=========================== -.5+<.^|*`la.tls.ie`* *`$rd`*, *`$rj`*, *`sym_ie_large`* +*Description :* -<.^|*`pcalau12i`* *`$rd`*, *`%ie_pc_hi20`*(*`sym_ie_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%ie_pc_lo12`*(*`sym_ie_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%ie64_pc_lo20`*(*`sym_ie_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%ie64_pc_hi12`*(*`sym_ie_large`*) -<.^|*`ldx.d`* *`$rd`*, *`$rd`*, *`$rj`* +[grid=none] +[frame=none] +[cols="120,20,860"] |=========================== +<.^|*`la.local`* +^.^|*:* +<.^|*`la.local`* can load the addresses of symbols defined within the current module. + +.2+<.<|*`la.global`* +.2+^.<|*:* +<.^|*`la.global`* can load addresses with symbols defined at any address. +<.^|*`la $rd`*, *`sym`* alias for *`la.global $rd`*, *`sym`*. +|=========================== + +*Usage :* + +* Method to load *`sym_local`*: + +[source] +---- +la.local $a0, sym_local // load sym_local address to $a0. +ld.{x} $a1, $a0, 0 // load sym_local to $a1. +---- + +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== + +.*`la.local`* Expand normally: +[source] +---- +pcalau12i $a0, %pc_hi20(sym_local) +addi.d $a0, $a0, %pc_lo12(sym_local) +ld.{x} $a1, $a0, 0 +---- + +.*`la.local`* Expand as *`la.abs`*: (GNU: *`-mla-local-with-abs`* LLVM: *`--mattr=+la-local-with-abs`*) +[source] +---- +lu12i.w $a0, %abs_hi20(sym_local) +ori $a0, $a0, %abs_lo12(sym_local) +lu32i.d $a0, %abs64_lo20(sym_local) +lu52i.d $a0, $a0, %abs64_hi12(sym_local) +ld.{x} $a1, $a0, 0 +---- + +* Method to load *`sym_local_large`*: + +[source] +---- +la.local $a0, $a1, sym_local_large // load sym_local_large address to $a0. +ld.{x} $a2, $a0, 0 // load sym_local_large to $a2. +---- + +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== + +.*`la.local`* Expand normally: +[source] +---- +pcalau12i $a0, %pc_hi20(sym_local_large) +addi.d $a1, $zero, %pc_lo12(sym_local_large) +lu32i.d $a1, %pc64_lo20(sym_local_large) +lu52i.d $a1, $a1, %pc64_hi12(sym_local_large) +add.d $a0, $a0, $a1 +ld.{x} $a2, $a0, 0 +---- + +.*`la.local`* Expand as *`la.abs`*: (GNU: *`-mla-local-with-abs`* LLVM: *`--mattr=+la-local-with-abs`*) +[source] +---- +lu12i.w $a0, %abs_hi20(sym_local) +ori $a0, $a0, %abs_lo12(sym_local) +lu32i.d $a0, %abs64_lo20(sym_local) +lu52i.d $a0, $a0, %abs64_hi12(sym_local) +ld.{x} $a2, $a0, 0 +---- + +* Method to load *`sym_global`*: + +[source] +---- +la.global $a0, sym_global // load sym_global to $a0. +la $a0, sym_global // load sym_global to $a0. +---- + +[NOTE] +==== +In normal expansion, *`la.global`* / *`la`* will directly load the content of the symbol instead of its address. In other cases, the address of the symbol is loaded. +==== + +.*`la.global`* Expand normally: +[source] +---- +pcalau12i $a0, %got_pc_hi20(sym_global) +ld.d $a0, $a0, %got_pc_lo12(sym_global) +---- + +.*`la.global`* Expand as *`la.pcrel`*: (GNU: *`-mla-global-with-pcrel`* LLVM: *`--mattr=+la-global-with-pcrel`*) +[source] +---- +pcalau12i $a0, %pc_hi20(sym_global) +addi.d $a0, $a0, %pc_lo12(sym_global) +ld.{x} $a1, $a0, 0 +---- + +.*`la.global`* Expand as *`la.abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +[source] +---- +lu12i.w $a0, %abs_hi20(sym_global) +ori $a0, $a0, %abs_lo12(sym_global) +lu32i.d $a0, %abs64_lo20(sym_global) +lu52i.d $a0, $a0, %abs64_hi12(sym_global) +ld.{x} $a1, $a0, 0 +---- + +* Method to load *`sym_global_large`*: + +[source] +---- +la.global $a0, $a1, sym_global_large // load sym_global_large to $a0. +---- + +[NOTE] +==== +In normal expansion, *`la.global`* will directly load the content of the symbol instead of its address. In other cases, the address of the symbol is loaded. +==== + +.*`la.global`* Expand normally: +[source] +---- +pcalau12i $a0, %got_pc_hi20(sym_global_large) +addi.d $a1, $zero, %got_pc_lo12(sym_global_large) +lu32i.d $a1, %got64_pc_lo20(sym_global_large) +lu52i.d $a1, $a1, %got64_pc_hi12(sym_global_large) +ldx.d $a0, $a0, $a1 +---- + +.*`la.global`* Expand as *`la.pcrel`*: (GNU: *`-mla-global-with-pcrel`* LLVM: *`--mattr=+la-global-with-pcrel`*) +[source] +---- +pcalau12i $a0, %pc_hi20(sym_global_large) +addi.d $a1, $zero, %pc_lo12(sym_global_large) +lu32i.d $a1, %pc64_lo20(sym_global_large) +lu52i.d $a1, $a1, %pc64_hi12(sym_global_large) +add.d $a0, $a0, $a1 +ld.{x} $a0, $a0, 0 +---- + +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== + +.*`la.global`* Expand as *`la.abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +[source] +---- +lu12i.w $a0, %abs_hi20(sym_global_large) +ori $a0, $a0, %abs_lo12(sym_global_large) +lu32i.d $a0, %abs64_lo20(sym_global_large) +lu52i.d $a0, $a0, %abs64_hi12(sym_global_large) +ld.{x} $a0, $a0, 0 +---- + +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== + +==== *9.4.2 `la`.`abs`* + +*Syntax:* + + opcode src1, src2 [options="header"] -[cols="50,50"] +[cols="60,10,30"] |=========================== -^.^|Macros Instruction -^.^|Machine Instructions +^.^|opcode +^.^|src1 +^.^|src2 + +^.^|*`la.abs`* +^.^|*`$rd`* +^.^|*`sym_abs`* +|=========================== + +*Description :* + +[grid=none] +[frame=none] +[cols="100,20,880"] +|=========================== +.3+<.<|*`la.abs`* +.3+^.<|*:* +<.^|It is used to load symbols defined at fixed addresses. +<.^|When loading, *`la.abs`* divides the address into four parts and uses four machine instructions to complete the loading operation for the symbol address. +<.^|For undefined weak symbols, it loads a constant value of 0. +|=========================== + +*Usage :* + +* Method to load *`sym_abs`*: + +[source] +---- +la.abs $a0, sym_abs // load sym_abs address to $a0. +ld.{x} $a2, $a0, 0 // load sym_abs to $a2. +---- + +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== + +.*`la.global`* Expand normally: +[source] +---- +lu12i.w $a0, %abs_hi20(sym_abs) +ori $a0, $a0, %abs_lo12(sym_abs) +lu32i.d $a0, %abs64_lo20(sym_abs) +lu52i.d $a0, $a0, %abs64_hi12(sym_abs) +ld.{x} $a2, $a0, 0 +---- -.2+<.^|*`la.tls.ld`* *`$rd`*, *`sym_ld`* +==== *9.4.3 `la`.`pcrel`* -<.^|*`pcalau12i`* *`$rd`*, *`%ld_pc_hi20`*(*`sym_ld`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%got_pc_lo12`*(*`sym_ld`*) +*Syntax:* -.5+<.^|*`la.tls.ld`* *`$rd`*, *`$rj`*, *`sym_ld_large`* + opcode src1, src2 -<.^|*`pcalau12i`* *`$rd`*, *`%ld_pc_hi20`*(*`sym_ld_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%got_pc_lo12`*(*`sym_ld_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%got64_pc_lo20`*(*`sym_ld_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%got64_pc_hi12`*(*`sym_ld_large`*) -<.^|*`ldx.d`* *`$rd`*, *`$rd`*, *`$rj`* +[options="header"] +[cols="70,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 + +^.^|*`la.pcrel`* +^.^|*`$rd`* +^.^|*`sym_pcrel`* |=========================== + opcode src1, src2, src3 + [options="header"] -[cols="50,50"] +[cols="60,10,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 +^.^|src3 + +^.^|*`la.pcrel`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_pcrel_large`* +|=========================== + +*Description :* + +[grid=none] +[frame=none] +[cols="100,20,880"] |=========================== -^.^|Macros Instruction -^.^|Machine Instructions +<.<|*`la.pcrel`* +^.<|*:* +<.^|Load symbols at minimal cost using the local symbol's PC-relative address. Undefined weak symbols cannot be loaded. +|=========================== + +*Usage :* + +* Method to load *`sym_pcrel`*: + +[source] +---- +la.pcrel $a0, sym_pcrel // load sym_pcrel address to $a0. +ld.{x} $a2, $a0, 0 // load sym_pcrel to $a2. +---- + +.*`la.global`* Expand normally: +[source] +---- +pcalau12i $a0, %pc_hi20(sym_pcrel) +addi.d $a0, $a0, %pc_lo12(sym_pcrel) +ld.{x} $a2, $a0, 0 +---- + +* Method to load *`sym_pcrel_large`*: + +[source] +---- +la.pcrel $a0, $a1, sym_pcrel_large // load sym_pcrel_large address to $a0. +ld.{x} $a2, $a0, 0 // load sym_pcrel_large to $a2. +---- -.2+<.^|*`la.tls.gd`* *`$rd`*, *`sym_gd`* +[NOTE] +==== +The {*`x`*} in *`ld`*.{*`x`*} instruction depends on the size of the symbol contents. +==== -<.^|*`pcalau12i`* *`$rd`*, *`%gd_pc_hi20`*(*`sym_gd`*) -<.^|*`ld.d`* *`$rd`*, *`$rd`*, *`%got_pc_lo12`*(*`sym_gd`*) +.*`la.global`* Expand normally: +[source] +---- +pcalau12i $a0, %pc_hi20(sym_pcrel_large) +addi.d $a1, $zero, %pc_lo12(sym_pcrel_large) +---- -.5+<.^|*`la.tls.gd`* *`$rd`*, *`$rj`*, *`sym_gd_large`* +[source] +---- +lu32i.d $a1, %pc64_lo20(sym_pcrel_large) +lu52i.d $a1, $a1, %pc64_hi12(sym_pcrel_large) +add.d $a0, $a0, $a1 +ld.{x} $a2, $a0, 0 +---- -<.^|*`pcalau12i`* *`$rd`*, *`%gd_pc_hi20`*(*`sym_gd_large`*) -<.^|*`addi.d`* *`$rj`*, *`$zero`*, *`%got_pc_lo12`*(*`sym_gd_large`*) -<.^|*`lu32i.d`* *`$rj`*, *`%got64_pc_lo20`*(*`sym_gd_large`*) -<.^|*`lu52i.d`* *`$rj`*, *`$rj`*, *`%got64_pc_hi12`*(*`sym_gd_large`*) -<.^|*`ldx.d`* *`$rd`*, *`$rd`*, *`$rj`* +==== *9.4.4 `la`.`got`* + +*Syntax:* + + opcode src1, src2 + +[options="header"] +[cols="70,10,20"] |=========================== +^.^|opcode +^.^|src1 +^.^|src2 + +^.^|*`la.got`* +^.^|*`$rd`* +^.^|*`sym_got`* +|=========================== + + opcode src1, src2, src3 [options="header"] -[cols="18,30,62"] +[cols="60,10,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 +^.^|src3 + +^.^|*`la.got`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_got_large`* |=========================== -^.^|Operand -^.^|ELF reloc type -^.^|Usage -<.^|*`%abs_hi20`* -<.^|*`R_LARCH_ABS_HI20`* -<.^|[31 … 12] bits of 32/64-bit absolute address +*Description :* -<.^|*`%abs_lo12`* -<.^|*`R_LARCH_ABS_LO12`* -<.^|[11 … 0] bits of 32/64-bit absolute address +[grid=none] +[frame=none] +[cols="100,20,880"] +|=========================== +<.<|*`la.got`* +^.<|*:* +<.^|Use the Global Offset Table (GOT) to load the address of a symbol from a double array constructed by the static linker. +|=========================== -<.^|*`%abs64_lo20`* -<.^|*`R_LARCH_ABS64_LO20`* -<.^|[51 … 32] bits of 64-bit absolute address +*Usage :* -<.^|*`%abs64_hi12`* -<.^|*`R_LARCH_ABS64_HI12`* -<.^|[63 … 52] bits of 64-bit absolute address +* Method to load *`sym_got`*: -<.^|*`%pc_hi20`* -<.^|*`R_LARCH_PCALA_HI20`* -<.^|[31 … 12] bits of 32/64-bit PC-relative offset +[source] +---- +la.got $a0, sym_got // load sym_got to $a0. +---- -<.^|*`%pc_lo12`* -<.^|*`R_LARCH_PCALA_LO12`* -<.^|[11 … 0] bits of 32/64-bit PC-relative offset +.*`la.got`* Expand normally: +[source] +---- +pcalau12i $a0, %got_pc_hi20(sym_got) +ld.d $a0, $a0, %got_pc_lo12(sym_got) +---- -<.^|*`%pc64_lo20`* -<.^|*`R_LARCH_PCALA64_LO20`* -<.^|[51 … 32] bits of 64-bit PC-relative offset +.*`la.got`* Expand *`abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +[source] +---- +lu12i.w $a0, %got_hi20(sym_got) +ori $a0, $a0, %got_lo12(sym_got) +lu32i.d $a0, %got64_lo20(sym_got) +lu52i.d $a0, $a0, %got64_hi12(sym_got) +ld.d $a0, $a0, 0 +---- -<.^|*`%pc64_hi12`* -<.^|*`R_LARCH_PCALA64_HI12`* -<.^|[63 … 52] bits of 64-bit PC-relative offset +* Method to load *`sym_got_large`*: -<.^|*`%got_pc_hi20`* -<.^|*`R_LARCH_GOT_PC_HI20`* -<.^|[31 … 12] bits of 32/64-bit PC-relative offset to GOT entry +[source] +---- +la.got $a0, $a1, sym_got_large // load sym_got_large to $a0. +---- -<.^|*`%got_pc_lo12`* -<.^|*`R_LARCH_GOT_PC_LO12`* -<.^|[11 … 0] bits of 32/64-bit PC-relative offset to GOT entry +.*`la.got`* Expand normally: +[source] +---- +pcalau12i $a0, %got_pc_hi20(sym_got_large) +addi.d $a1, $zero, %got_pc_lo12(sym_got_large) +lu32i.d $a1, %got64_pc_lo20(sym_got_large) +lu52i.d $a1, $a1, %got64_pc_hi12(sym_got_large) +ldx.d $a0, $a0, $a1 +---- -<.^|*`%got64_pc_lo20`* -<.^|*`R_LARCH_GOT64_PC_LO20`* -<.^|[51 … 32] bits of 64-bit PC-relative offset to GOT entry +==== *9.4.5 `la`.`tls`.{`le` / `ie` / `ld` / `gd` / `desc`}* -<.^|*`%got64_pc_hi12`* -<.^|*`R_LARCH_GOT64_PC_HI12`* -<.^|[63 … 52] bits of 64-bit PC-relative offset to GOT entry +*Syntax:* -<.^|*`%le_hi20`* -<.^|*`R_LARCH_TLS_LE_HI20`* -<.^|[31 … 12] bits of 32/64-bit offset from TP register + opcode src1, src2 -<.^|*`%le_lo12`* -<.^|*`R_LARCH_TLS_LE_LO12`* -<.^|[11 … 0] bits of 32/64-bit offset from TP register +[options="header"] +[cols="70,10,20"] +|=========================== +^.^|opcode +^.^|src1 +^.^|src2 -<.^|*`%ie_pc_hi20`* -<.^|*`R_LARCH_TLS_IE_PC_HI20`* -<.^|[31 … 12] bits of 32/64-bit PC-relative offset to TLS IE GOT entry +^.^|*`la.tls.le`* +^.^|*`$rd`* +^.^|*`sym_le`* -<.^|*`%ie_pc_lo12`* -<.^|*`R_LARCH_TLS_IE_PC_LO12`* -<.^|[11 … 0] bits of 32/64-bit PC-relative offset to TLS IE GOT entry +^.^|*`la.tls.ie`* +^.^|*`$rd`* +^.^|*`sym_ie`* -<.^|*`%ie64_pc_lo20`* -<.^|*`R_LARCH_TLS_IE64_PC_LO20`* -<.^|[51 … 32] bits of 64-bit PC-relative offset to TLS IE GOT entry +^.^|*`la.tls.ld`* +^.^|*`$rd`* +^.^|*`sym_ld`* -<.^|*`%ie64_pc_hi12`* -<.^|*`R_LARCH_TLS_IE64_PC_HI12`* -<.^|[63 … 52] bits of 64-bit PC-relative offset to TLS IE GOT entry +^.^|*`la.tls.gd`* +^.^|*`$rd`* +^.^|*`sym_gd`* -<.^|*`%ld_pc_hi20`* -<.^|*`R_LARCH_TLS_LD_PC_HI20`* -<.^|[51 … 32] bits of 64-bit PC-relative offset to TLS LD GOT entry +^.^|*`la.tls.desc`* +^.^|*`$rd`* +^.^|*`sym_desc`* +|=========================== + + opcode src1, src2, src3 -<.^|*`%gd_pc_hi20`* -<.^|*`R_LARCH_TLS_GD_PC_HI20`* -<.^|[63 … 52] bits of 64-bit PC-relative offset to TLS GD GOT entry +[options="header"] +[cols="60,10,10,20"] |=========================== +^.^|opcode +^.^|src1 +^.^|src2 +^.^|src3 + +^.^|*`la.tls.ie`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_ie_large`* + +^.^|*`la.tls.ld`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_ld_large`* + +^.^|*`la.tls.gd`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_gd_large`* + +^.^|*`la.tls.desc`* +^.^|*`$rd`* +^.^|*`$rj`* +^.^|*`sym_desc_large`* +|=========================== + +* *`la.tls.ld`* is alias for *`la.tls.gd`*. + +*Description :* + +* *`Thread Local Storage`* (*`TLS`*) is a space (*`TLS block`*) that is unique to a thread in a user program. +** *`$tp`* is used to support *`TLS`*. + +[grid=none] +[frame=none] +[cols="130,20,850"] +|=========================== +<.^|*`la.tls.le`* +^.^|*:* +<.^|Load *`$tp`*-relative offset of *`TLS`* symbol. + +<.^|*`la.tls.ie`* +^.^|*:* +<.^|Load runtime *`$tp`*-relative offset of *`TLS`* symbol from *`GOT`* entry. + +<.^|*`la.tls.ld`* +^.^|*:* +<.^|Alias for *`la.tls.gd`* . + +<.^|*`la.tls.gd`* +^.^|*:* +<.^|Load the runtime information that is passed to *`__tls_get_addr`*, which is used to access *`TLS`* symbol. + +<.<|*`la.tls.desc`* +^.<|*:* +<.^|A more flexible address for loading symbols from *`TLS`*, which is often used for link optimization. +|=========================== + +*Usage :* + +* Method to load *`sym_le`* address: + +[source] +---- +la.tls.le $a0, sym_le // load sym_le address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_le address to $a0. +---- + +.*`la.tls.le`* Expand normally: +[source] +---- +lu12i.w $a0, %le_hi20(sym_le) +ori $a0, $a0, %le_lo12(sym_le) +add.{w/d} $a0, $a0, $tp +---- + +* Method to load *`sym_le_large`* address: + +[source] +---- +la.tls.le $a0, sym_le_large // load sym_le_large address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_le_large address to $a0. +---- + +.*`la.tls.le`* Expand normally: +[source] +---- +lu12i.w $a0, %le_hi20(sym_le_large) +ori $a0, $a0, %le_lo12(sym_le_large) +lu32i.d $a0, %le64_hi20(sym_le_large) +lu52i.d $a0, $a0, %le64_hi12(sym_le_large) +add.{w/d} $a0, $a0, $tp +---- + +* Method to load *`sym_ie`* address: + +[source] +---- +la.tls.ie $a0, sym_ie // load sym_ie address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_ie address to $a0. +---- + +.*`la.tls.ie`* Expand normally: +[source] +---- +pcalau12i $a0, %ie_pc_hi20(sym_ie) +ld.d $a0, $a0, %ie_pc_lo12(sym_ie) +add.{w/d} $a0, $a0, $tp +---- + +.*`la.tls.ie`* Expand *`abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +[source] +---- +lu12i.w $a0, %ie_hi20(sym_ie) +ori $a0, $a0, %ie_lo12(sym_ie) +lu32i.d $a0, %ie64_lo20(sym_ie) +lu52i.d $a0, $a0, %ie64_hi12(sym_ie) +ld.d $a0, $a0, 0 +---- + +* Method to load *`sym_ie_large`* address: + +[source] +---- +la.tls.ie $a0, $a1, sym_ie_large // load sym_ie_large address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_ie_large address to $a0. +---- + +.*`la.tls.ie`* Expand normally: +[source] +---- +pcalau12i $a0, %ie_pc_hi20(sym_ie_large) +addi.d $a1, $zero, %ie_pc_lo12(sym_ie_large) +lu32i.d $a1, %ie64_pc_lo20(sym_ie_large) +lu52i.d $a1, $a1, %ie64_pc_hi12(sym_ie_large) +ldx.d $a0, $a0, $a1 +add.{w/d} $a0, $a0, $tp +---- + +* Method to load *`sym_gd`* address: (*`la.tls.gd`* alias for *`la.tls.ld`*) + +[source] +---- +la.tls.gd $a0, sym_gd // load __tls_get_addr args to $a0. +bl %plt(__tls_get_addr) // __tls_get_addr ret sym_gd address to $a0. +---- + +.*`la.tls.gd`* Expand normally: +[source] +---- +pcalau12i $a0, %gd_pc_hi20(sym_gd) +addi.d $a0, $a0, %got_pc_lo12(sym_gd) +bl %plt(__tls_get_addr) +---- + +.*`la.tls.gd`* Expand *`abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +[source] +---- +lu12i.w $a0, %gd_hi20(sym_gd) +ori $a0, $a0, %got_lo12(sym_gd) +lu32i.d $a0, %got64_lo20(sym_gd) +lu52i.d $a0, $a0, %got64_hi12(sym_gd) +bl %plt(__tls_get_addr) +---- + +* Method to load *`sym_gd_large`* address: + +[source] +---- +la.tls.gd $a0, $a1, sym_gd_large // load __tls_get_addr args to $a0. +bl %plt(__tls_get_addr) // __tls_get_addr ret sym_gd address to $a0. +---- + +.*`la.tls.gd`* Expand normally: +[source] +---- +pcalau12i $a0, %gd_pc_hi20(sym_gd_large) +addi.d $a1, $zero, %got_pc_lo12(sym_gd_large) +lu32i.d $a1, %got64_pc_lo20(sym_gd_large) +lu52i.d $a1, $a1, %got64_pc_hi12(sym_gd_large) +add.d $a0, $a0, $a1 +bl %plt(__tls_get_addr) +---- + +* Method to load *`sym_desc`* address: + +[source] +---- +la.tls.desc $a0, sym_desc // load sym_desc address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_desc address to $a0. +---- + +.*`la.tls.desc`* Expand normally +[source] +---- +pcalau12i $a0, %desc_pc_hi20(sym_desc) +addi.d $a0, $a0, %desc_pc_lo12(sym_desc) +ld.d $ra, $a0, %desc_ld(sym_desc) +jirl $ra, $ra, %desc_call(sym_desc) +add.{w/d} $a0, $a0, $tp +---- + +.*`la.tls.desc`* Expand *`abs`*: (GNU: *`-mla-global-with-abs`* LLVM: *`--mattr=+la-global-with-abs`*) +---- +lu12i.w $a0, %desc_hi20(sym_desc) +ori $a0, $a0, %desc_lo12(sym_desc) +lu32i.d $a0, %desc64_lo20(sym_desc) +lu52i.d $a0, $a0, %desc64_hi12(sym_desc) +ld.d $ra, $a0, %desc_ld(sym_desc) +jirl $ra, $ra, %desc_call(sym_desc) +add.{w/d} $a0, $a0, $tp +---- + +* Method to load *`sym_desc_large`* address: + +[source] +---- +la.tls.desc $a0, $a1, sym_desc_large // load sym_desc address offset to $a0. +add.{w/d} $a0, $a0, $tp // load sym_desc address to $a0. +---- + +.*`la.tls.desc`* Expand normally +[source] +---- +pcalau12i $a0, %desc_pc_hi20(sym_desc_large) +addi.d $a1, $zero, %desc_pc_lo12(sym_desc_large) +lu32i.d $a1, %desc64_pc_lo20(sym_desc_large) +lu52i.d $a1, $a1, %desc64_pc_hi12(sym_desc_large) +add.d $a0, $a0, $a1 +ld.d $ra, $a0, %desc_ld(sym_desc_large) +jirl $ra, $ra, %desc_call(sym_desc_large) +add.{w/d} $a0, $a0, $tp +---- + + diff --git a/adoc/Preface/About_This_Book.adoc b/adoc/Preface/About_This_Book.adoc index 2fff305..7571c9d 100644 --- a/adoc/Preface/About_This_Book.adoc +++ b/adoc/Preface/About_This_Book.adoc @@ -1,7 +1,7 @@ === *About This Book* [.text-justify] -This book provides tutorial and reference information on the *`LoongArch`* Assembly Language Program. This includes *`LoongArch`* data type, register, address, and inline assemblers in the C and C++ compilers. It describes the assembly language mnemonics, the pseudo-instructions, the macros, and directives available to assembly language programmers. It also describes the format of the *`LoongArch`* ELF file. +This book provides tutorial and reference information on the *`LoongArch`* Assembly Language Program. It covers *`LoongArch`* data types, registers, addressing, and inline assembly in C and C++ compilers. Additionally, it describes the assembly language mnemonics, pseudo-instructions, macros, and directives available to assembly language programmers. It also details the format of the *`LoongArch`* ELF file. include::Intended_Audience.adoc[] diff --git a/adoc/Preface/Change_History.adoc b/adoc/Preface/Change_History.adoc index c19860f..1677fb6 100644 --- a/adoc/Preface/Change_History.adoc +++ b/adoc/Preface/Change_History.adoc @@ -13,5 +13,9 @@ <.^|2024-04-10 ^.^|V1.0 -<.^|This update has added descriptions of instructions in *`LoongArch Architecture manual v1.10`* to this Guide and corrected some incorrect descriptions. +<.^|This update has added descriptions of instructions from the *`LoongArch Architecture manual v1.10`* to this Guide and corrected some incorrect descriptions. + +<.^|2024-10-17 +^.^|V1.1 +<.^|Fixed some incorrect descriptions. Updated the description of the macro instruction in CHAPTER 9. Added informations on the usage of registers in the CFI macro instructions and the *`.option`* directive. |========================== diff --git a/adoc/Preface/Intended_Audience.adoc b/adoc/Preface/Intended_Audience.adoc index d7ea03c..1ba6d78 100644 --- a/adoc/Preface/Intended_Audience.adoc +++ b/adoc/Preface/Intended_Audience.adoc @@ -1,4 +1,4 @@ ==== *Intended Audience* [.text-justify] -This book is written for all developers who are producing applications using compilation tools. It assumes that you are an experienced assembly language developer and that you are familiar with the *`LoongArch`* architecture. +This book is written for all developers who are producing applications using compilation tools. It assumes that you are an experienced assembly language developer and are familiar with the *`LoongArch`* architecture. diff --git a/adoc/Preface/Preface.adoc b/adoc/Preface/Preface.adoc index c31b7f2..a060c49 100644 --- a/adoc/Preface/Preface.adoc +++ b/adoc/Preface/Preface.adoc @@ -1,9 +1,10 @@ == *Preface* [.text-justify] -This preface introduces the *`LoongArch`* Assembly Language Programming Guide. +This preface introduces the *`LoongArch`* Assembly Language Programming Guide. -This document aims to provide guidance to assembly programmers targeting the standard *`LoongArch`* assembly language, which common open-source assemblers like *`GNU`* as and *`LLVM`*'s assembler support. Other assemblers might not support the same directives or pseudo instructions; their dialects are outside the scope of this document. +[.text-justify] +This document aims to provide guidance for assembly programmers targeting the standard *`LoongArch`* assembly language, which is supported by common open-source assemblers such as *`GNU`* as and *`LLVM`*'s assembler. Other assemblers may not support the same directives or pseudo instructions; and their dialects are beyond the scope of this document. include::About_This_Book.adoc[] diff --git a/adoc/Preface/Using_This_Book.adoc b/adoc/Preface/Using_This_Book.adoc index aadd775..b9118b8 100644 --- a/adoc/Preface/Using_This_Book.adoc +++ b/adoc/Preface/Using_This_Book.adoc @@ -7,5 +7,5 @@ For more information, please refer to: * https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html[LoongArch Architecture manual] -* http://sysdev.loongson.cn/attachments/download/91249/la-abi.pdf[LoongArch Application Binary Interface manual] -==== \ No newline at end of file +* https://github.com/loongson/la-abi-specs/releases/tag/v2.30/la-abi.pdf[LoongArch Application Binary Interface manual] +==== diff --git a/fonts/CM_Unicode/OFL.txt b/fonts/CM_Unicode/OFL.txt new file mode 100644 index 0000000..a55bb6b --- /dev/null +++ b/fonts/CM_Unicode/OFL.txt @@ -0,0 +1,103 @@ +Copyright (C) Authors of original metafont fonts: +Donald Ervin Knuth (cm, concrete fonts) +1995, 1996, 1997 J"org Knappen, 1990, 1992 Norbert Schwarz (ec fonts) +1992-2006 A.Khodulev, O.Lapko, A.Berdnikov, V.Volovich (lh fonts) +1997-2005 Claudio Beccari (cb greek fonts) +2002 FUKUI Rei (tipa fonts) +2003-2005 Han The Thanh (Vietnamese fonts) +1996-2005 Walter Schmidt (cmbright fonts) + +Copyright (C) 2003-2009, Andrey V. Panov (panov@canopus.iacp.dvo.ru), +with Reserved Font Family Name "Computer Modern Unicode fonts". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/CM_Unicode/cmunbi.ttf b/fonts/CM_Unicode/cmunbi.ttf new file mode 100644 index 0000000..3b529ed Binary files /dev/null and b/fonts/CM_Unicode/cmunbi.ttf differ diff --git a/fonts/CM_Unicode/cmunbx.ttf b/fonts/CM_Unicode/cmunbx.ttf new file mode 100644 index 0000000..2c7198e Binary files /dev/null and b/fonts/CM_Unicode/cmunbx.ttf differ diff --git a/fonts/CM_Unicode/cmunrm.ttf b/fonts/CM_Unicode/cmunrm.ttf new file mode 100644 index 0000000..1c3fff0 Binary files /dev/null and b/fonts/CM_Unicode/cmunrm.ttf differ diff --git a/fonts/CM_Unicode/cmuntb.ttf b/fonts/CM_Unicode/cmuntb.ttf new file mode 100644 index 0000000..f940901 Binary files /dev/null and b/fonts/CM_Unicode/cmuntb.ttf differ diff --git a/fonts/CM_Unicode/cmunti.ttf b/fonts/CM_Unicode/cmunti.ttf new file mode 100644 index 0000000..993d5c0 Binary files /dev/null and b/fonts/CM_Unicode/cmunti.ttf differ diff --git a/fonts/CM_Unicode/cmuntt.ttf b/fonts/CM_Unicode/cmuntt.ttf new file mode 100644 index 0000000..1651877 Binary files /dev/null and b/fonts/CM_Unicode/cmuntt.ttf differ diff --git a/fonts/Merriweather/Merriweather-Bold.ttf b/fonts/Merriweather/Merriweather-Bold.ttf new file mode 100644 index 0000000..b668e8c Binary files /dev/null and b/fonts/Merriweather/Merriweather-Bold.ttf differ diff --git a/fonts/Merriweather/Merriweather-BoldItalic.ttf b/fonts/Merriweather/Merriweather-BoldItalic.ttf new file mode 100644 index 0000000..df062a3 Binary files /dev/null and b/fonts/Merriweather/Merriweather-BoldItalic.ttf differ diff --git a/fonts/Merriweather/Merriweather-Italic.ttf b/fonts/Merriweather/Merriweather-Italic.ttf new file mode 100644 index 0000000..90f3273 Binary files /dev/null and b/fonts/Merriweather/Merriweather-Italic.ttf differ diff --git a/fonts/Merriweather/Merriweather-Regular.ttf b/fonts/Merriweather/Merriweather-Regular.ttf new file mode 100644 index 0000000..666a322 Binary files /dev/null and b/fonts/Merriweather/Merriweather-Regular.ttf differ diff --git a/fonts/Merriweather/OFL.txt b/fonts/Merriweather/OFL.txt new file mode 100644 index 0000000..ab1138c --- /dev/null +++ b/fonts/Merriweather/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2016 The Merriweather Project Authors (https://github.com/EbenSorkin/Merriweather), with Reserved Font Name "Merriweather". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/fonts/Noto_Serif/NotoSerif-Bold.ttf b/fonts/Noto_Serif/NotoSerif-Bold.ttf new file mode 100644 index 0000000..219b8cf Binary files /dev/null and b/fonts/Noto_Serif/NotoSerif-Bold.ttf differ diff --git a/fonts/Noto_Serif/NotoSerif-BoldItalic.ttf b/fonts/Noto_Serif/NotoSerif-BoldItalic.ttf new file mode 100644 index 0000000..2dfc953 Binary files /dev/null and b/fonts/Noto_Serif/NotoSerif-BoldItalic.ttf differ diff --git a/fonts/Noto_Serif/NotoSerif-Italic.ttf b/fonts/Noto_Serif/NotoSerif-Italic.ttf new file mode 100644 index 0000000..50ad343 Binary files /dev/null and b/fonts/Noto_Serif/NotoSerif-Italic.ttf differ diff --git a/fonts/Noto_Serif/NotoSerif-Regular.ttf b/fonts/Noto_Serif/NotoSerif-Regular.ttf new file mode 100644 index 0000000..521539c Binary files /dev/null and b/fonts/Noto_Serif/NotoSerif-Regular.ttf differ diff --git a/fonts/Noto_Serif/OFL.txt b/fonts/Noto_Serif/OFL.txt new file mode 100644 index 0000000..d4e7958 --- /dev/null +++ b/fonts/Noto_Serif/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2012 Google Inc. All Rights Reserved. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/la-asm-manual.adoc b/la-asm-manual.adoc index fc37c26..fa00276 100644 --- a/la-asm-manual.adoc +++ b/la-asm-manual.adoc @@ -1,20 +1,23 @@ = `Assembly Language Programming Guide` LoongArch(TM) Loongson Technology Corporation Limited -v1.0, 2024-04-10 +v1.1, 2024-10-17 :docinfo: shared :doctype: book :toc: macro :toc-title: Contents :toclevels: 4 -:source-highlighter: coderay toc::[] - + == *Preamble* + +[.text-justify] This is the official documentation of the `Assembly Language Programming Guide` for the `LoongArch` Architecture. -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. +[.text-justify] +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. -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. +[.text-justify] +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. <<< diff --git a/themes/la-asm-manual-pdf.yml b/themes/la-asm-manual-pdf.yml new file mode 100644 index 0000000..9483659 --- /dev/null +++ b/themes/la-asm-manual-pdf.yml @@ -0,0 +1,158 @@ +# ----------------------------------------------------------------------------- +# Asciidoctor PDF Theme for LoongArch documents. +# ----------------------------------------------------------------------------- +page: + layout: portrait + margin: [10mm, 15mm, 18mm, 15mm] + size: a4 + +base: + font_color: #333333 + font_family: Noto Serif + font_style: normal + font_size: 10 + line_height: 1.1 + vertical_spacing: 11 + +heading: + font_color: #d71520 + font_family: Merriweather + h1_font_family: CMU Serif + h1_font_size: floor($base_font_size * 1.7) + h2_font_size: floor($base_font_size * 1.3) + h3_font_size: round($base_font_size * 1.1) + h4_font_size: round($base_font_size * 1.0) + font_style: bold + line_height: 1 + margin_bottom: $vertical_spacing / 1.5 + margin_top: $vertical_spacing / 1.5 + +code: + font_color: #333333 +# font_family: Courier Prime Sans + font_family: CMU Typewriter + font_style: normal + font_size: 10 + background_color: #f6f6f6 +# border_color: #0f80aa + border_color: #333333 + border_radius: 2 + line_height: 1.1 + +#caption: +# font_family: CMU Serif +# font_style: normal +# font_size: 10 + +literal: + font_family: CMU Typewriter + font_color: $heading_font_color + font_style: normal + +link: + font_color: #002FA7 + +description_list: + description_indent: $base_font_size * 2.5 + +outline_list: + indent: $base_font_size * 2.5 + +title_page: + font_family: Noto Serif + font_color: #000000 +# background_color: #1d4e89 + background_color: #ffffff + align: right + #logo: + # top: 10% + # image: image:images/puzzle_stamp_white.svg[width=30%, align=center] + title: + top: 30% + font_color: $heading_font_color + font_size: $base_font_size * 4.25 + font_family: CMU Serif + font_style: bold + line_height: 0.9 + subtitle: + font_size: $base_font_size * 2.00 + font_family: Noto Serif + font_style: normal + line_height: 1 + authors: + margin_top: $base_font_size * 29.25 + font_size: $base_font_size * 1.5 + font_family: Noto Serif + font_style: normal + revision: + margin_top: $base_font_size * 0.5 + font_family: Noto Serif + font_style: normal + +toc: + line_height: 1.25 + h1: + font_style: bold + dot_leader: + content: ". " + font_color: A9A9A9 + levels: 1 2 3 + + +table: + border_width: 1 + cell: + padding: 3 + head: + font_size: 10 + body: + font_size: 9 + foot: + font_size: 9 + +footer: + font_size: 8 + border_color: dddddd + border_width: 0.25 + height: 38.5 + line_height: 1 + padding: [5.5, 1, 0, 1] + vertical_align: top + recto: + right: + content: '{document-title} | © Loongson' + left: + content: '{page-number}' + verso: + left: + content: $footer_recto_right_content + right: + content: '{page-number}' + + +## ---------------------------------------------------------------------------- +## Fonts +## ---------------------------------------------------------------------------- +font: + catalog: + Noto Serif: + normal: Noto_Serif/NotoSerif-Regular.ttf + bold: Noto_Serif/NotoSerif-Bold.ttf + italic: Noto_Serif/NotoSerif-Italic.ttf + bold_italic: Noto_Serif/NotoSerif-BoldItalic.ttf + + Merriweather: + normal: Merriweather/Merriweather-Regular.ttf + bold: Merriweather/Merriweather-Bold.ttf + italic: Merriweather/Merriweather-Italic.ttf + bold_italic: Merriweather/Merriweather-BoldItalic.ttf + + CMU Serif: + normal: CM_Unicode/cmunrm.ttf + bold: CM_Unicode/cmunbx.ttf + italic: CM_Unicode/cmunti.ttf + bold_italic: CM_Unicode/cmunbi.ttf + + CMU Typewriter: + normal: CM_Unicode/cmuntt.ttf + bold: CM_Unicode/cmuntb.ttf