diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b9879d2b..92e8b6218 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,6 +67,14 @@ jobs: with: name: Italian manual (PDF) path: ./build/docs/it/pdf/EduMIPS64.pdf + # + # Disabled due to not working properly + # + # - name: Upload Simplified Chinese Manual PDF + # uses: actions/upload-artifact@v3.1.2 + # with: + # name: Chinese manual (PDF) + # path: ./build/docs/zh/pdf/EduMIPS64.pdf - name: Upload JAR uses: actions/upload-artifact@v3.1.2 @@ -137,6 +145,7 @@ jobs: deploy-web: name: Deploy web application + permissions: write-all runs-on: ubuntu-latest needs: build-web steps: diff --git a/build.gradle.kts b/build.gradle.kts index 2231ecd64..7f63c9438 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,6 +51,9 @@ application { val codename: String by project val version: String by project + + + // Specify Java source/target version and source encoding. tasks.compileJava { sourceCompatibility = "17" @@ -75,6 +78,10 @@ tasks.register("htmlDocsIt") { workDir = "${projectDir}/docs/user/en/src" command = buildDocsCmd("it", "html") } +tasks.register("htmlDocsZh") { + workDir = "${projectDir}/docs/user/zh/src" + command = buildDocsCmd("zh", "html") +} tasks.register("pdfDocsEn") { workDir = "${projectDir}/docs/user/en/src" @@ -86,10 +93,15 @@ tasks.register("pdfDocsIt") { command = buildDocsCmd("it", "pdf") } +tasks.register("pdfDocsZh") { + workDir = "${projectDir}/docs/user/zh/src" + command = buildDocsCmd("zh", "pdf") +} + // Catch-all task for documentation tasks.create("allDocs") { - tasks = listOf("htmlDocsIt", "htmlDocsEn", "pdfDocsEn", "pdfDocsIt") + tasks = listOf("htmlDocsIt","htmlDocsZh", "htmlDocsEn", "pdfDocsEn", "pdfDocsZh", "pdfDocsIt") description = "Run all documentation tasks" } @@ -115,6 +127,14 @@ tasks.create("copyHelpIt") { into ("${docsDir}/user/it") dependsOn("htmlDocsIt") } +tasks.create("copyHelpZh") { + from("${buildDir}/docs/zh") { + include("html/**") + exclude("**/_sources/**") + } + into ("${docsDir}/user/zh") + dependsOn("htmlDocsZh") +} tasks.create("copyHelp") { from("docs/") { @@ -124,6 +144,7 @@ tasks.create("copyHelp") { into ("${docsDir}") dependsOn("copyHelpEn") dependsOn("copyHelpIt") + dependsOn("copyHelpZh") } /* @@ -268,7 +289,7 @@ tasks.create("msi"){ } println("Creating EduMIPS64-${version}.msi."); - val cmd = "jpackage.exe --main-jar edumips64-${version}.jar --input ./build/libs/ --app-version ${version} --name EduMIPS64 --description \"Educational MIPS64 CPU Simulator\" --vendor \"EduMIPS64 Development Team\" --copyright \"Copyright ${LocalDateTime.now().year}, EduMIPS64 development Team\" --license-file ./LICENSE --win-shortcut --win-dir-chooser --win-menu --type msi --icon ./src/main/resources/images/ico.ico --win-per-user-install" + val cmd = "jpackage.exe --main-jar edumips64-${version}.jar --input ./build/libs/ --app-version ${version} --name EduMIPS64 --description \"Educational MIPS64 CPU Simulator\" --vendor \"EduMIPS64 Development Team\" --copyright \"Copyright ${LocalDateTime.now().year}, EduMIPS64 development Team\" --license-file ./LICENSE --win-shortcut --win-dir-chooser --win-menu --type msi --icon ./src/main/resources/images/ico.ico --win-per-user-install --java-options -Dfile.encoding=utf-8" commandLine(cmd.split(" ")); } } diff --git a/docs/user/en/src/examples.rst b/docs/user/en/src/examples.rst index fb9ea12ef..7ef1f3f6f 100644 --- a/docs/user/en/src/examples.rst +++ b/docs/user/en/src/examples.rst @@ -198,7 +198,7 @@ usual, the strings containing the error message and the success message. In the .text section, we save the params_sys4 address to register r14, we save in the memory cells for the SYSCALL parameters the file descriptor (that we suppose to have in $s2) and the address from where we must take the bytes to -weite. +write. Next we can call SYSCALL 3, and then we call the print_string function passing as argument error_3 or ok_message, according to the success of the diff --git a/docs/user/zh/EduMIPS64.hs b/docs/user/zh/EduMIPS64.hs new file mode 100644 index 000000000..a64b6ac52 --- /dev/null +++ b/docs/user/zh/EduMIPS64.hs @@ -0,0 +1,38 @@ + + + + + + + + EduMIPS64 帮助 + + + top + + + + + TOC + + javax.help.TOCView + EduMIPS64TOC.xml + + + + main window + + + EduMIPS64 帮助 + + javax.help.BackAction + javax.help.ForwardAction + javax.help.HomeAction + javax.help.PrintAction + + + diff --git a/docs/user/zh/EduMIPS64Index.xml b/docs/user/zh/EduMIPS64Index.xml new file mode 100644 index 000000000..7be54912e --- /dev/null +++ b/docs/user/zh/EduMIPS64Index.xml @@ -0,0 +1,4 @@ + + + + diff --git a/docs/user/zh/EduMIPS64TOC.xml b/docs/user/zh/EduMIPS64TOC.xml new file mode 100644 index 000000000..52c81abcb --- /dev/null +++ b/docs/user/zh/EduMIPS64TOC.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/user/zh/JavaHelpSearch/DOCS b/docs/user/zh/JavaHelpSearch/DOCS new file mode 100644 index 000000000..6381dbf0a Binary files /dev/null and b/docs/user/zh/JavaHelpSearch/DOCS differ diff --git a/docs/user/zh/JavaHelpSearch/DOCS.TAB b/docs/user/zh/JavaHelpSearch/DOCS.TAB new file mode 100644 index 000000000..863184d19 --- /dev/null +++ b/docs/user/zh/JavaHelpSearch/DOCS.TAB @@ -0,0 +1 @@ +e_u_'@2,+뺾̪꾫ꪺꪾꮻꪾ꾪꾪꾪ꮪꮺ못ꪫꮺꫮꪪ뫪 \ No newline at end of file diff --git a/docs/user/zh/JavaHelpSearch/OFFSETS b/docs/user/zh/JavaHelpSearch/OFFSETS new file mode 100644 index 000000000..6a9ff0224 --- /dev/null +++ b/docs/user/zh/JavaHelpSearch/OFFSETS @@ -0,0 +1 @@ +ZlmH >GjH @ |fD \ No newline at end of file diff --git a/docs/user/zh/JavaHelpSearch/POSITIONS b/docs/user/zh/JavaHelpSearch/POSITIONS new file mode 100644 index 000000000..4cc178d0d Binary files /dev/null and b/docs/user/zh/JavaHelpSearch/POSITIONS differ diff --git a/docs/user/zh/JavaHelpSearch/SCHEMA b/docs/user/zh/JavaHelpSearch/SCHEMA new file mode 100644 index 000000000..49d06f7ec --- /dev/null +++ b/docs/user/zh/JavaHelpSearch/SCHEMA @@ -0,0 +1,2 @@ +JavaSearch 1.0 +TMAP bs=2048 rt=1 fl=-1 id1=1045 id2=1 diff --git a/docs/user/zh/JavaHelpSearch/TMAP b/docs/user/zh/JavaHelpSearch/TMAP new file mode 100644 index 000000000..999d88f84 Binary files /dev/null and b/docs/user/zh/JavaHelpSearch/TMAP differ diff --git a/docs/user/zh/Map.jhm b/docs/user/zh/Map.jhm new file mode 100644 index 000000000..fe575a68b --- /dev/null +++ b/docs/user/zh/Map.jhm @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/user/zh/img/Back.png b/docs/user/zh/img/Back.png new file mode 100644 index 000000000..49930845e Binary files /dev/null and b/docs/user/zh/img/Back.png differ diff --git a/docs/user/zh/img/Forward.png b/docs/user/zh/img/Forward.png new file mode 100644 index 000000000..11d5b48a9 Binary files /dev/null and b/docs/user/zh/img/Forward.png differ diff --git a/docs/user/zh/img/Home.png b/docs/user/zh/img/Home.png new file mode 100644 index 000000000..f953f2de6 Binary files /dev/null and b/docs/user/zh/img/Home.png differ diff --git a/docs/user/zh/img/Print.png b/docs/user/zh/img/Print.png new file mode 100644 index 000000000..c8a362d02 Binary files /dev/null and b/docs/user/zh/img/Print.png differ diff --git a/docs/user/zh/img/exception_cfg.png b/docs/user/zh/img/exception_cfg.png new file mode 100644 index 000000000..4c8a79d49 Binary files /dev/null and b/docs/user/zh/img/exception_cfg.png differ diff --git a/docs/user/zh/img/exception_mask_cfg.png b/docs/user/zh/img/exception_mask_cfg.png new file mode 100644 index 000000000..71afc81a8 Binary files /dev/null and b/docs/user/zh/img/exception_mask_cfg.png differ diff --git a/docs/user/zh/img/fcsr_register.png b/docs/user/zh/img/fcsr_register.png new file mode 100644 index 000000000..1ba8457dd Binary files /dev/null and b/docs/user/zh/img/fcsr_register.png differ diff --git a/docs/user/zh/img/fpu_rounding.png b/docs/user/zh/img/fpu_rounding.png new file mode 100644 index 000000000..29168d2df Binary files /dev/null and b/docs/user/zh/img/fpu_rounding.png differ diff --git a/docs/user/zh/img/invalid_operation_trap.png b/docs/user/zh/img/invalid_operation_trap.png new file mode 100644 index 000000000..71738237f Binary files /dev/null and b/docs/user/zh/img/invalid_operation_trap.png differ diff --git a/docs/user/zh/src/Makefile b/docs/user/zh/src/Makefile new file mode 100644 index 000000000..072d26df8 --- /dev/null +++ b/docs/user/zh/src/Makefile @@ -0,0 +1,138 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python3 -msphinx +PAPER = +BUILDDIR = ../output + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " pdf to make PDF files using rst2pdf" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) --version + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/EduMIPS64.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/EduMIPS64.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/EduMIPS64" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/EduMIPS64" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +pdf: + $(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished. The PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + diff --git a/docs/user/zh/src/conf.py b/docs/user/zh/src/conf.py new file mode 100644 index 000000000..91a25338c --- /dev/null +++ b/docs/user/zh/src/conf.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# +# EduMIPS64 documentation build configuration file, created by +# sphinx-quickstart on Tue Apr 26 23:10:10 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. +# +# Note: all the common configuration of the EduMIPS64 documentation is stored +# in docs/common_conf.py. This file just imports all the identifiers from that +# module and adds language-specific configuration items. + +import sys, os +sys.path.append(os.path.abspath("../..")) +from common_conf import * + +pdf_stylesheets = ['sphinx', 'kerning', 'a4', 'zh_CN.json', 'chinese'] +pdf_font_path = [os.path.abspath(".\\docs\\zh\\src"),'C:\\Windows\\Fonts'] +pdf_language = "zh_CN" +source_encoding = "utf-8" +language = "zh_CN" +copyright = u'2011, Andrea Spadaccini (and the EduMIPS64 development team)' +man_pages = [ + ('index', 'edumips64', u'EduMIPS64 Documentation', + [u'Andrea Spadaccini (and the EduMIPS64 development team)'], 1) +] +latex_documents = [ + ('index', 'EduMIPS64.tex', u'EduMIPS64 Documentation', + u'Andrea Spadaccini (and the EduMIPS64 development team)', 'manual'), +] diff --git a/docs/user/zh/src/examples.rst b/docs/user/zh/src/examples.rst new file mode 100644 index 000000000..d27c4da9a --- /dev/null +++ b/docs/user/zh/src/examples.rst @@ -0,0 +1,223 @@ +代码示例 +============= +在本章中,您将看到一些对理解 EduMIPS64 如何工作非常有用的示例列表,以了解 EduMIPS64 如何工作。 + +SYSCALL +------- + +重要的是要了解 SYSCALL 1-4 的示例引用了`print.s` 文件,这是 SYSCALL 5 的示例。如果要运行 +示例,应将该示例的内容复制到一个名为`print.s` 的文件,并将其包含在代码中。 + +有些示例会使用已存在的文件描述符,即使它并不真正存在。如果要运行这些示例,请使用 SYSCALL 1 示例打开一个文件。 + +SYSCALL 0 +~~~~~~~~~ +调用 SYSCALL 0 时,程序停止执行。 +示例:: + + .code + daddi r1, r0, 0 ; saves 0 in R1 + syscall 0 ; exits + +SYSCALL 1 +~~~~~~~~~ +打开文件的示例程序:: + + .data + error_op: .asciiz "Error opening the file" + ok_message: .asciiz "All right" + params_sys1: .asciiz "filename.txt" + .word64 0xF + + .text + open: daddi r14, r0, params_sys1 + syscall 1 + daddi $s0, r0, -1 + dadd $s2, r0, r1 + daddi $a0,r0,ok_message + bne r1,$s0,end + daddi $a0,r0,error_op + + end: jal print_string + syscall 0 + + #include print.s + +在前两行中,我们将包含错误信息和成功信息的字符串写入内存,并将其传递给 print_string 函数。 +给它们加上两个标签。print_string 函数包含在 print.s 文件中。 + +接下来,我们向内存写入 SYSCALL 1 所需的数据(第 4、5 行)、要打开的文件的路径(第 6、7 行 +要打开的文件的路径(如果我们使用 读取 或 读/写模式),并在下一个内存单元中写入一个定义打开模式的整数。 + +.. 有关文件打开方式的更多信息,请参阅 \ref{sys1}。 + +在本例中,文件使用以下模式打开: +| `o_rdwr` | `o_creat` | `_append`。数字 +数字 15(0xF,以 16 为基数)来自这三种模式的值之和(3 + 4 + 8)。 + +我们给这些数据加上一个标签,以便以后使用。 + +在 .text 部分,我们将 params_sys1 的地址(对编译器来说是一个数字)保存在寄存器中。 +在 .text 部分,我们将 params_sys1 的地址(对编译器来说是一个数字)保存在寄存器 r14 中;接下来我们可以调用 SYSCALL 1 并将 r1 的内容保存在 $sys1 中。 +将 r1 的内容保存在 $s2 中,这样我们就可以在程序的其余部分中使用它了 +(例如,使用其他 SYSCALL)。 + +然后调用 print_string 函数,将 error_op 作为参数传递,如果 +r1等于-1(第 13-14 行),否则将 ok_message 作为参数(第 12 和 14 行)。 +则将 ok_message 作为参数(第 12 和 16 行)。 + +SYSCALL 2 +~~~~~~~~~ +关闭文件的示例程序:: + + .data + params_sys2: .space 8 + error_cl: .asciiz "Error closing the file" + ok_message: .asciiz "All right" + + .text + close: daddi r14, r0, params_sys2 + sw $s2, params_sys2(r0) + syscall 2 + daddi $s0, r0, -1 + daddi $a0, r0, ok_message + bne r1, $s0, end + daddi $a0, r0, error_cl + + end: jal print_string + syscall 0 + + #include print.s + +首先,我们为 SYSCALL 2 的唯一参数,即必须关闭的文件的文件描述符(第 2 行)保存一些内存,并给它一个标签,以便以后访问。 + +接下来,我们将包含错误信息和成功信息的字符串放入内存,这些字符串将传递给 print_string 函数(第 3、4 行)。 + +在 .text 部分,我们将 params_sys2 的地址保存在 r14 中;然后我们就可以 调用 SYSCALL 2。 + +现在我们使用 error_cl 作为参数调用 print_string 函数,如果 r1 +则调用 print_string 函数(第 13 行),如果一切顺利,则使用 ok_message 作为参数调用 print_string 函数(第 11 行)。则使用 ok_message 作为参数调用该函数(第 11 行)。 + +**注:** 此列表需要寄存器 $s2 包含要调用的文件的文件描述符。文件描述符。 + +SYSCALL 3 +~~~~~~~~~ +从文件读取 16 个字节并保存到内存的示例程序:: + + .data + params_sys3: .space 8 + ind_value: .space 8 + .word64 16 + error_3: .asciiz "Error while reading from file" + ok_message: .asciiz "All right" + + value: .space 30 + + .text + read: daddi r14, r0, params_sys3 + sw $s2, params_sys3(r0) + daddi $s1, r0, value + sw $s1, ind_value(r0) + syscall 3 + daddi $s0, r0, -1 + daddi $a0, r0,ok_message + bne r1, $s0,end + daddi $a0, r0,error_3 + + end: jal print_string + syscall 0 + + #include print.s + +.data 部分的前 4 行包含 SYSCALL 3 的参数、我们必须从中读取的文件描述符、SYSCALL 必须保存读取数据的内存地址以及要读取的字节数。我们给那些稍后必须访问的参数加上标签。接下来,像往常一样,我们将包含错误信息和成功信息的字符串放入其中。 + +在 .text 部分,我们将 params_sys3 的地址保存到寄存器 r14 中,并在 SYSCALL 参数的内存单元中保存文件描述符(我们假设保存在 $s2 中)和用于保存读取字节的地址。 + +接下来,我们可以调用 SYSCALL 3,然后调用 print_string 函数 +根据操作成功与否,将 error_3 或 ok_message 作为参数传递。 + +SYSCALL 4 +~~~~~~~~~ +向文件写入字符串的示例程序:: + + .data + params_sys4: .space 8 + ind_value: .space 8 + .word64 16 + error_4: .asciiz "Error writing to file" + ok_message: .asciiz "All right" + value: .space 30 + + .text + + write: daddi r14, r0,params_sys4 + sw $s2, params_sys4(r0) + daddi $s1, r0,value + sw $s1, ind_value(r0) + syscall 4 + daddi $s0, r0,-1 + daddi $a0, r0,ok_message + bne r1, $s0,end + daddi $a0, r0,error_4 + + end: jal print_string + syscall 0 + + #include print.s + +.data 部分的前 4 行包含 SYSCALL 4 的参数、我们必须读取的文件描述符、SYSCALL 必须读取的内存地址、要写入的字节数。我们给那些稍后必须访问的参数加上标签。接下来,像往常一样,我们将包含错误信息和成功信息的字符串放入其中。 + +在 .text 部分,我们将 params_sys4 的地址保存到寄存器 r14 中,在 SYSCALL 参数的内存单元中保存文件描述符(我们假设保存在 $s2 中)和我们必须读取写入字节的地址。 + +接下来我们可以调用 SYSCALL 3,然后根据操作的成功与否调用 print_string 函数,参数为 error_3 或 ok_message。 + + +SYSCALL 5 +~~~~~~~~~ +包含将 $a0 中的字符串打印到标准输出的函数的示例程序:: + + .data + params_sys5: .space 8 + + .text + print_string: + sw $a0, params_sys5(r0) + daddi r14, r0, params_sys5 + syscall 5 + jr r31 + +第二行用于为 SYSCALL 必须打印的字符串保存空间,由 .text 部分的第一条指令填充,该指令假定 \$a0 中有要打印的字符串地址。 + +下一条指令将字符串的地址放入 r14,然后我们就可以调用 SYSCALL 5 打印字符串了。最后一条指令将程序计数器设置为 r31 中的内容,这是 MIPS 通常的调用习惯。 + +一个更复杂的 SYSCALL 5 使用示例 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SYSCALL 5 使用了一种并不简单的参数传递机制,下面的示例将对此进行说明:: + + .data + format_str: .asciiz "%dth of %s:\n%s version %i.%i is being tested!" + s1: .asciiz "June" + s2: .asciiz "EduMIPS64" + fs_addr: .space 4 + .word 5 + s1_addr: .space 4 + s2_addr: .space 4 + .word 0 + .word 5 + test: + .code + daddi r5, r0, format_str + sw r5, fs_addr(r0) + daddi r2, r0, s1 + daddi r3, r0, s2 + sd r2, s1_addr(r0) + sd r3, s2_addr(r0) + daddi r14, r0, fs_addr + syscall 5 + syscall 0 + +格式字符串的地址被放入 R5,其内容随后被保存到内存中的 fs_addr 地址。字符串参数的地址被保存到 s1_addr 和 s2_addr。这两个字符串参数与格式字符串中的两个 %s 占位符相匹配。 + +从内存来看,与占位符相匹配的参数显然是紧跟在格式字符串地址之后存储的:数字与整数参数相匹配,而地址与字符串参数相匹配。在 s1_addr 和 s2_addr 位置,存放着我们要打印的两个字符串的地址,而不是 %s 占位符。 + +示例的执行将显示 SYSCALL 5 如何处理复杂的格式字符串,如存储在 format_str 中的字符串。 diff --git a/docs/user/zh/src/fpu.rst b/docs/user/zh/src/fpu.rst new file mode 100644 index 000000000..3c17568a2 --- /dev/null +++ b/docs/user/zh/src/fpu.rst @@ -0,0 +1,385 @@ +浮点单元 +=================== + +本章 [#]_ 介绍 EduMIPS64 仿真的浮点运算单元(FPU)。 + +在第一段中,我们将介绍双倍格式、IEEE 754 标准中定义的特殊浮点数值以及浮点计算可能引发的异常情况。 + +第二段介绍 EduMIPS64 如何允许用户启用或禁用 IEEE 浮点陷阱。 + +第三段介绍如何在源程序中指定双精度数和特殊值。 + +在第四段中,我们将介绍 FPU 用来表示其状态的 FCSR 寄存器。它包含四舍五入、比较运算的布尔结果以及处理 IEEE 浮点异常的策略等信息。 + +在第五段,也是最后一段,我们将介绍 EduMIPS64 中实现的所有 MIPS64 浮点指令。 + +在开始讨论 FPU 之前,我们将浮点双精度数域定义为[-1.79E308,-4.94E-324] ⋃ {0} ⋃ [4.94E-324,1.79E308]。 + +.. [#] 本章是马西莫-特鲁比亚(Massimo Trubia)学士学位论文 "Progetto e implementazione di un modello di Floating Point Unit per un simulatore di CPU MIPS64 "的一部分。 + +.. _special-values: + +特殊价值 +-------------- +浮点运算允许程序员选择在进行无效运算时是否停止计算。在这种情况下,零与零之间的除法或负数的平方根等运算必须产生一个结果,而这个结果如果不是数字(NaN),就会被视为不同的结果。 + +.. _nan: + +NaN 或无效操作 +************************ +IEEE 浮点运算标准(IEEE 754)规定,无效的运算操作可以在程序运行时发出错误信号(使用 IEEE 异常**无效操作**的陷阱), +或者返回特殊值 QNan(退出非数值)。另一个 NaN 值是 SNan(Signalling Not a Number),一旦检测到它是操作数之一, +就会无条件地引发相同的陷阱。这个值在应用程序中很少使用,历史上一直用于初始化变量。 + +.. _zeroes: + +零或下溢 +******************** +该标准定义的另一个特殊值是零。由于 double 格式的域中不包含零,因此它被视为一个特殊值。 +零值有正零值和负零值两种:前者用于表示负数∈ ]-4.94E-324,0[) 时,并且需要一个结果(而不是允许**下溢**陷阱); +后者用于表示的数字∈ [0,4.94E-324[]时,并且禁止下溢陷阱。 + +.. _infinites: + +无穷大还是溢出 +********************** +当程序试图表示一个绝对值极大的数值(∈ ]-∞,-1.79E308[ ⋃ ]1.79E308,+∞[),而这个数值超出了双数值的范围时,CPU 会返回 -∞ 或 +∞。另一种方法是触发异常**溢出**条件陷阱。 + +在除以零的情况下,也可以返回无穷小数值;在这种情况下,无穷小数值的符号由零的符号和红利的符号的乘积给出。除以零**的陷阱也会出现。 + +.. _exception-configuration: + +异常配置 +----------------------- +EduMIPS64 允许用户通过 *配置* → *设置* 窗口中的 *FPU 异常* 选项卡,启用或禁用 5 个 IEEE 异常中 4 个的陷阱。 +如果禁用了其中任何一个,将返回相应的特殊值(如 :ref:`special-values` 中所述)。 + +.. In the situation depicted in +.. Figure :ref:`fig-exception_cfg`, in which some checkbox are selected, if the +.. CPU does not mask synchronous exceptions (Figure +.. :ref:`fig-exception_mask_cfg`) the selected traps will be raised if the IEEE +.. exceptional condition is encountered (Figure +.. :ref:`fig-invalid_operation_trap`). + +.. TODO: see how to include it in the resulting in-app help +.. .. _fig-exception_cfg: + .. figure:: ../../../img/exception_cfg.png + :scale: 50% + + Trap configuration for IEEE exceptions + + .. _fig-exception_mask_cfg: + .. figure:: ../../../img/exception_mask_cfg.png + :scale: 50% + + Option that masks all the synchronous exceptions + + .. _fig-invalid_operation_trap: + .. figure:: ../../../img/invalid_operation_trap.png + :scale: 50% + + Trap notification window + + +.. _double-directive: + +.double 指令 +--------------------- +``.double`` 指令必须在源文件的 ``.data`` 部分使用,它允许为一个 *double* 值分配一个内存单元。 + +该指令有两种使用方式:: + + 变量名:.double double_number + 变量名:.double 关键字 + +其中,``double_number`` 可以用扩展符号(``1.0,0.003``)或科学符号(`3.7E-12,0.5E32`)表示。 +关键字``可以是``POSITIVEINFINITY``、``NEGATIVEINFINITY``、``POSITIVEZERO``、``NEGATIVEZERO``、`SNAN``和`QNAN``, +因此可以直接在内存中插入特殊值。 + +FCSR 寄存器 +----------------- +FCSR(浮点控制状态寄存器)是控制 FPU 多个功能方面的寄存器。它的长度为 32 位,在统计窗口中表示。 + + +**FCC** 字段宽 8 位,从 0 到 7。条件指令(``C.EQ.D,C.LT.D``)使用它来保存两个寄存器之间比较的布尔结果。 + +Cause、Enables 和 Flag 字段用于处理 :ref:`special-values` 中描述的 IEEE 异常动态。每个字段由 5 个位组成,分别是 V(无效操作)、Z(除以零)、O(溢出)、U(下溢)和 I(不精确);后者尚未使用。 + +如果在程序执行过程中出现相应的 IEEE 异常,**Clause** 字段位将被置位。 + +启用**字段位通过配置窗口设置,显示启用陷阱的 IEEE 异常。 + +**Flag** 字段显示已发生的异常,但由于陷阱未针对该异常启用,因此返回了特殊值( :ref:`special-values` 中描述的特殊值)。 + +**RM** 字段描述了当前使用的将浮点数转换为整数的舍入方法(请参阅 "CVT.L.D "指令的描述)。 + +指令集 +--------------- +本节介绍 EduMIPS64 实现的 MIPS64 FPU 指令;它们按字母顺序排列。指令执行的操作使用以下符号描述:第 i 个存储单元表示为 ``memory[i]``,FCSR 寄存器的 FCC 字段表示为 ``FCSR_FCC[cc]``, ``cc`` ∈ [0,7]。 + +在某些指令中,为了避免歧义,寄存器被表示为 ``GPR[i]`` 和 ``FPR[i]``, ``i`` ∈ [0,31],但在大多数情况下,我们只使用 ``rx`` 或 ``fx`` 符号,其中 ``x``∈ {d,s,t}。三个字母用来表示每个寄存器的用途(目的寄存器、源寄存器、第三寄存器)。最后,转换操作返回的值用以下符号表示:``convert_conversiontype(register[,rounding_type])``、 +其中 ``rounding_type`` 参数是可选的。 + +有关 FPU 指令的一些示例,请访问 ``http://www.edumips.org/attachment/wiki/Upload/FPUMaxSamples.rar``。 + +* `ADD.D fd, fs, ft` + + *描述*: `fd =fs+ft`。 + + *异常*: 如果结果无法根据 IEEE 754 表示,将产生溢出和下溢陷阱。如果fs或ft包含QNaN或SNan,或者执行了无效操作(+∞ - ∞),则会产生无效操作。 + +* `BC1F cc, offset`. + + *描述*: `if FCSR_FCC[cc] == 0 then branch`. + + 如果 ``FCSR_FCC[cc]`` 为 false,则执行 PC 相关分支。 + + *示例*:: + + C.EQ.D 7,f1,f2 + BC1F 7,label + + 在本例中,``C.EQ.D`` 检查``f1``和``f2``是否相等,并将比较结果写入 FCSR 寄存器 FCC 字段的第 7 位。之后,如果比较结果为 0(假),`BC1F`` 将跳转到`label`。 + +* `BC1T cc, offset` + + *描述*: `if FCSR_FCC[cc] == 1 then branch``. + + 如果 ``FCSR_FCC[cc]`` 为真,则执行 PC 相关分支。 + + *示例*:: + + C.EQ.D 7,f1,f2 + BC1T 7,label + + 在本例中,``C.EQ.D`` 检查``f1``和``f2``是否相等,并将比较结果写入 FCSR 寄存器 FCC 字段的第 7 位。之后,如果比较结果为 1(假),则 ``BC1F`` 跳转到 ``label`` 。 + +* `C.EQ.D cc, fs, ft`. + + *描述*: `FCSR_FCC[cc] = (fs==ft)`` + + 检查 `fs` 是否等于 `ft`,并将比较结果保存在 `FCSR_FCC[cc]` 中。请参阅 ``BC1T``, ``BC1F`` 的示例。 + + *异常*: 如果 ``fs`` 或 ``ft`` 包含 QNaN(如果启用则触发陷阱) o SNaN(总是触发陷阱),则可能抛出无效操作。 + +* `C.LT.D cc,fs,ft`。 + + *描述*: `FCSR_FCC[cc] = (fs { lang_en.setState(true); lang_it.setState(false); + lang_zhcn.setState(false); configStore.putString(ConfigKey.LANGUAGE, "en"); initMenuItems(); setFrameTitles(); @@ -906,6 +912,7 @@ private JMenuBar createMenuBar() { lang_it.addActionListener(e -> { lang_it.setState(true); lang_en.setState(false); + lang_zhcn.setState(false); configStore.putString(ConfigKey.LANGUAGE, "it"); initMenuItems(); setFrameTitles(); @@ -913,6 +920,28 @@ private JMenuBar createMenuBar() { // mainFrame.setVisible(true); }); + try { + lang_zhcn = new JCheckBoxMenuItem( + CurrentLocale.getString("MenuItem.SIMPLIFIED_CHINESE"), + new ImageIcon(IMGLoader.getImage("zhcn.png")), + configStore.getString(ConfigKey.LANGUAGE).equals("zhcn")); + + lang.add(lang_zhcn); + } catch (IOException e) { + log.log(Level.SEVERE, "Could not create simplified chinese language checkbox.", e); + } + + lang_zhcn.addActionListener(e -> { + lang_zhcn.setState(true); + lang_en.setState(false); + lang_it.setState(false); + configStore.putString(ConfigKey.LANGUAGE, "zhcn"); + initMenuItems(); + setFrameTitles(); + front.updateLanguageStrings(); + // mainFrame.setVisible(true); + }); + // ---------------- HELP MENU @@ -946,7 +975,6 @@ private JMenuBar createMenuBar() { // ---------------- WINDOW MENU // - tile = new JMenuItem("Tile"); tile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK)); tile.addActionListener(e -> tileWindows()); window.add(tile); diff --git a/src/main/java/org/edumips64/utils/CurrentLocale.java b/src/main/java/org/edumips64/utils/CurrentLocale.java index 171ddf7bc..7a59192f9 100644 --- a/src/main/java/org/edumips64/utils/CurrentLocale.java +++ b/src/main/java/org/edumips64/utils/CurrentLocale.java @@ -90,6 +90,7 @@ public static void setConfig(ConfigStore config) { en.put("MenuItem.RUN_TO", "Run"); en.put("MenuItem.ITALIAN", "Italian"); en.put("MenuItem.ENGLISH", "English"); + en.put("MenuItem.SIMPLIFIED_CHINESE", "Simplified Chinese"); en.put("MenuItem.DIN_TRACEFILE", "Write _Dinero tracefile..."); en.put("MenuItem.FORWARDING", "Enable _forwarding"); en.put("MenuItem.WARNINGS", "Enable _warnings"); @@ -97,6 +98,7 @@ public static void setConfig(ConfigStore config) { en.put("MenuItem.DIN_FRONTEND", "_Dinero frontend..."); en.put("MenuItem.MANUAL", "_Manual..."); en.put("MenuItem.STOP", "Stop"); + en.put("MenuItem.TILE", "Tile"); en.put("ABOUT", "About EduMIPS64"); en.put("REGISTERS", "Registers"); en.put("MEMORY", "Data"); @@ -325,6 +327,7 @@ public static void setConfig(ConfigStore config) { it.put("MenuItem.RUN_TO", "Esegui"); it.put("MenuItem.ITALIAN", "Italiano"); it.put("MenuItem.ENGLISH", "Inglese"); + it.put("MenuItem.SIMPLIFIED_CHINESE", "Cinese semplificato"); it.put("MenuItem.DIN_TRACEFILE", "Scrivi tracefile _Dinero..."); it.put("MenuItem.FORWARDING", "Abilita _forwarding"); it.put("MenuItem.WARNINGS", "Abilita _warning"); @@ -332,6 +335,7 @@ public static void setConfig(ConfigStore config) { it.put("MenuItem.DIN_FRONTEND", "_Dinero frontend..."); it.put("MenuItem.MANUAL", "_Manuale..."); it.put("MenuItem.STOP", "Ferma"); + it.put("MenuItem.TILE", "Tile"); it.put("ABOUT", "Informazioni su EduMIPS64"); it.put("REGISTERS", "Registri"); it.put("MEMORY", "Memoria"); @@ -510,6 +514,242 @@ public static void setConfig(ConfigStore config) { it.put("CLI.RUNNING", "In esecuzione"); it.put("LOG.HEADLESS_MSG", "Impossibile avviare la GUI in un ambiente headless."); languages.put("it", it); + + //Chinese Hashmap + HashMap zhcn = new HashMap<>(); + zhcn.put("DOUBLE_EXT_TOO_LARGE", "指数超过32位"); + zhcn.put("LABELADDRESSINVALID", "无效偏移量:应在-32767和32768之间(16位有符号)"); + zhcn.put("FP_INVALID_OPERATION", "执行了无效操作"); + zhcn.put("FP_DIV_BY_ZERO", "执行了除以零的操作"); + zhcn.put("FP_OVERFLOW", "浮点溢出,绝对值太大"); + zhcn.put("FP_UNDERFLOW", "浮点下溢,绝对值太小"); + zhcn.put("BYTEINCODE", ".byte 指令出现在代码段中"); + zhcn.put("WORD16INCODE", ".word16 指令出现在代码段中"); + zhcn.put("WORDINCODE", ".word指令出现在代码段中"); + zhcn.put("WORD32INCODE", ".word32 指令出现在代码段中"); + zhcn.put("SPACEINCODE", ".space 指令出现在代码段中"); + zhcn.put("INVALIDVALUE", "无效值"); + zhcn.put("INVALIDCODE", "无效代码"); + zhcn.put("INVALIDCODEFORDATA", "数据的无效代码"); + zhcn.put("INVALIDREGISTER", "无效寄存器"); + zhcn.put("INVALIDIMMEDIATE", "无效立即数值"); + zhcn.put("UNKNOWNSYNTAX", "未知语法"); + zhcn.put("SEPARATORMISS", "缺少分隔符"); + zhcn.put("LABELNOTFOUND", "找不到标签"); + zhcn.put("VALUEISNOTUNSIGNED", "有符号值:需要一个无符号值"); + zhcn.put("GUI_STEP_ERROR", "CPU步进错误"); + zhcn.put("GUI_PARSER_ERROR", "解析错误"); + zhcn.put("INCLUDE_LOOP", "包含循环"); + zhcn.put("INT_FORMAT_EXCEPTION", "您必须输入一个整数值"); + zhcn.put("ERROR_LABEL", "访问内存元素时出错。也许您已经达到了 EduMIPS64 内存的极限。"); + zhcn.put("ERROR", "错误"); + zhcn.put("FILE_NOT_FOUND", "找不到文件"); + zhcn.put("SYSCALL5_ERROR", "写入标准输出时出错"); + zhcn.put("Menu.FILE", "文件 (_F)"); + zhcn.put("Menu.EXECUTE", "执行 (_X)"); + zhcn.put("Menu.CONFIGURE", "配置 (_C)"); + zhcn.put("Menu.WINDOW", "窗口 (_W)"); + zhcn.put("Menu.HELP", "帮助 (_H)"); + zhcn.put("Menu.CHANGE_LANGUAGE", "更改语言"); + zhcn.put("Menu.TOOLS", "工具 (_T)"); + zhcn.put("Menu.CHANGE_PIPELINE_COLORS", "更改流水线颜色"); + zhcn.put("MenuItem.OPEN", "打开...(_O)"); + zhcn.put("MenuItem.OPENLAST", "打开最近的文件..."); + zhcn.put("MenuItem.RESET", "重置 (_R)"); + zhcn.put("MenuItem.EXIT", "退出 (_X)"); + zhcn.put("MenuItem.SINGLE_CYCLE", "单周期"); + zhcn.put("MenuItem.MULTI_CYCLE", "多周期"); + zhcn.put("MenuItem.MULTI_STEP", "多步骤"); + zhcn.put("MenuItem.RUN_TO", "运行"); + zhcn.put("MenuItem.ITALIAN", "意大利语"); + zhcn.put("MenuItem.ENGLISH", "英语"); + zhcn.put("MenuItem.SIMPLIFIED_CHINESE", "简体中文"); + zhcn.put("MenuItem.DIN_TRACEFILE", "写入 Dinero 跟踪文件...(_D)"); + zhcn.put("MenuItem.FORWARDING", "启用转发 (_F)"); + zhcn.put("MenuItem.WARNINGS", "启用警告 (_W)"); + zhcn.put("MenuItem.ABOUT_US", "关于我们... (_A)"); + zhcn.put("MenuItem.DIN_FRONTEND", "Dinero 前端... (_D)"); + zhcn.put("MenuItem.MANUAL", "手册... (_M)"); + zhcn.put("MenuItem.STOP", "停止"); + zhcn.put("MenuItem.TILE", "平铺"); + zhcn.put("ABOUT", "关于 EduMIPS64"); + zhcn.put("REGISTERS", "寄存器"); + zhcn.put("MEMORY", "数据"); + zhcn.put("CODE", "代码"); + zhcn.put("PIPELINE", "流水线"); + zhcn.put("LOGGER", "日志"); + zhcn.put("IO", "输入/输出"); + zhcn.put("EXCEPTION", "异常"); + zhcn.put("FPUINFO", "浮点单元"); + zhcn.put("FPUFCSR", "FCSR 寄存器"); + zhcn.put("ADDRESS", "地址"); + zhcn.put("HEXREPR", "十六进制表示"); + zhcn.put("COMMENT", "注释"); + zhcn.put("LABEL", "标签"); + zhcn.put("INSTRUCTION", "指令"); + zhcn.put("STATS", "统计数据"); + zhcn.put("PROSIM", "MIPS64 处理器模拟器"); + zhcn.put("GUI_WARNING", "警告"); + zhcn.put("WINMIPS64_NOT_MIPS64", "该指令属于 WinMIPS64 指令集,但不是合法的 MIPS64 指令"); + zhcn.put("HALT_NOT_PRESENT", "缺少HALT指令:它将自动插入到文件的末尾"); + zhcn.put("ROW", "行"); + zhcn.put("COLUMN", "列"); + zhcn.put("IMMEDIATE_TOO_LARGE", "立即数值太大"); + zhcn.put("WORD_TOO_LARGE", "字值太大"); + zhcn.put("WORD32_TOO_LARGE", "字32值太大"); + zhcn.put("WORD16_TOO_LARGE", "字16值太大"); + zhcn.put("BYTE_TOO_LARGE", "字节值太大"); + zhcn.put("5BIT_IMMEDIATE_TOO_LARGE", "5位立即数值太大"); + zhcn.put("3BIT_IMMEDIATE_TOO_LARGE", "3位立即数值太大"); + zhcn.put("VALUE_MISS", "缺少内存单元的值"); + zhcn.put("SAMELABEL", "标签已存在"); + zhcn.put("CHOOSE_COLOR", "选择一种颜色"); + zhcn.put("EXECUTION", "执行"); + zhcn.put("CYCLES", "周期"); + zhcn.put("CYCLE", "周期"); + zhcn.put("INSTRUCTIONS", "指令"); + zhcn.put("CPI", "CPI (每条指令的周期数)"); + zhcn.put("RAWS", "RAW 停顿"); + zhcn.put("RAW", "RAW 停顿"); + zhcn.put("BYTES", "字节"); + zhcn.put("STALLS", "停顿"); + zhcn.put("WAWS", "WAW 停顿"); + zhcn.put("WARS", "WAR 停顿"); + zhcn.put("STRUCTS_DIVNOTAVAILABLE", "结构停顿(除法器不可用)"); + zhcn.put("STRUCTS_MEMNOTAVAILABLE", "结构停顿(内存不可用)"); + zhcn.put("BTS", "分支已采用停顿"); + zhcn.put("BMS", "分支错误预测停顿"); + zhcn.put("CSIZE", "代码大小"); + zhcn.put("Config.APPEARANCE", "外观"); + zhcn.put("Config.BEHAVIOR", "行为"); + zhcn.put("Config.MAIN", "主要设置"); + zhcn.put("Config.ITEM", "设置..."); + zhcn.put("Config.WARNINGS", "启用警告"); + zhcn.put("Config.WARNINGS.tip", "在编译时启用警告"); + zhcn.put("Config.FORWARDING", "启用转发"); + zhcn.put("Config.FORWARDING.tip", "在流水线中启用转发"); + zhcn.put("Config.LONGDOUBLEVIEW", "长/双精度内存单元视图"); + zhcn.put("Config.LONGDOUBLEVIEW.tip", "在状态栏中切换长和双精度内存单元的可视化方式"); + zhcn.put("Config.VERBOSE", "在多步骤执行中与 CPU 同步图形显示"); + zhcn.put("Config.VERBOSE.tip", "启用详细的多步骤执行模式"); + zhcn.put("Config.N_STEP", "步骤数目"); + zhcn.put("Config.N_STEP.tip", "每条指令的步骤数目"); + zhcn.put("Config.FPUEXCEPTIONS", "FPU 异常"); + zhcn.put("Config.INVALID_OPERATION", "无效操作异常"); + zhcn.put("Config.INVALID_OPERATION.tip", "启用浮点无效操作异常"); + zhcn.put("Config.OVERFLOW", "溢出异常"); + zhcn.put("Config.OVERFLOW.tip", "启用浮点溢出异常 "); + zhcn.put("Config.UNDERFLOW", "下溢异常"); + zhcn.put("Config.UNDERFLOW.tip", "启用浮点下溢异常 "); + zhcn.put("Config.DIVIDE_BY_ZERO", "除以零异常"); + zhcn.put("Config.DIVIDE_BY_ZERO.tip", "启用浮点除以零异常"); + zhcn.put("Config.FPUROUNDING", "FPU 舍入"); + zhcn.put("Config.NEAREST", "最近"); + zhcn.put("Config.NEAREST.tip", "将结果舍入到最接近的可表示值,当值相等时舍入到偶数"); + zhcn.put("Config.TOWARDZERO", "向零舍入"); + zhcn.put("Config.TOWARDZERO.tip", "永远不会增加被舍弃小数前的数字(即截断)"); + zhcn.put("Config.TOWARDS_PLUS_INFINITY", "向正无穷舍入"); + zhcn.put("Config.TOWARDS_PLUS_INFINITY.tip", "向正无穷舍入"); + zhcn.put("Config.TOWARDS_MINUS_INFINITY", "向负无穷舍入"); + zhcn.put("Config.TOWARDS_MINUS_INFINITY.tip", "向负无穷舍入"); + zhcn.put("Config.IFCOLOR", "取指颜色"); + zhcn.put("Config.IFCOLOR.tip", "设置IF颜色"); + zhcn.put("Config.IDCOLOR", "译码颜色"); + zhcn.put("Config.IDCOLOR.tip", "设置译码颜色"); + zhcn.put("Config.EXCOLOR", "执行颜色"); + zhcn.put("Config.EXCOLOR.tip", "设置执行颜色"); + zhcn.put("Config.MEMCOLOR", "存储器颜色"); + zhcn.put("Config.MEMCOLOR.tip", "设置存储器颜色"); + zhcn.put("Config.WBCOLOR", "写回颜色"); + zhcn.put("Config.WBCOLOR.tip", "设置写回颜色"); + zhcn.put("Config.FPADDERCOLOR", "FP 加法器颜色"); + zhcn.put("Config.FPADDERCOLOR.tip", "设置 FP 加法器颜色"); + zhcn.put("Config.FPMULTIPLIERCOLOR", "FP乘法器颜色"); + zhcn.put("Config.FPMULTIPLIERCOLOR.tip", "设置FP乘法器颜色"); + zhcn.put("Config.FPDIVIDERCOLOR", "FP 除法器颜色"); + zhcn.put("Config.FPDIVIDERCOLOR.tip", "设置 FP 除法器颜色"); + zhcn.put("Config.SLEEP_INTERVAL", "周期间隔(毫秒)"); + zhcn.put("Config.SLEEP_INTERVAL.tip", "在详细模式下,每个周期执行前要经过的毫秒数"); + zhcn.put("Config.SYNCEXC-MASKED", "屏蔽同步异常"); + zhcn.put("Config.SYNCEXC-MASKED.tip", "使模拟器忽略除以零和整数溢出异常"); + zhcn.put("Config.SYNCEXC-TERMINATE", "同步异常终止"); + zhcn.put("Config.SYNCEXC-TERMINATE.tip", "在除以零和整数溢出异常时停止模拟"); + zhcn.put("Config.FONTSIZE", "字体大小"); + zhcn.put("Config.FONTSIZE.tip", "字体的大小"); + zhcn.put("StatusBar.WELCOME", "欢迎使用 EduMIPS64"); + zhcn.put("StatusBar.DECIMALVALUE", "十进制值"); + zhcn.put("StatusBar.OFREGISTER", "R 寄存器的值为 "); + zhcn.put("StatusBar.OFREGISTERFP", "F 寄存器的值为 "); + zhcn.put("StatusBar.MEMORYCELL", " 的地址为 "); + zhcn.put("Manual.CAPTION", "用户指南"); + zhcn.put("Manual.INTRO", "介绍"); + zhcn.put("Manual.GUI", "图形用户界面"); + zhcn.put("Manual.IS", "指令"); + zhcn.put("Manual.SYSCALL", "系统调用"); + zhcn.put("ErrorDialog.ROW", "行"); + zhcn.put("ErrorDialog.COLUMN", "列"); + zhcn.put("ErrorDialog.LINE", "行"); + zhcn.put("ErrorDialog.DESCRIPTION", "描述"); + zhcn.put("ErrorDialog.MSG0", "代码包含"); + zhcn.put("ErrorDialog.MSG1", "个错误和"); + zhcn.put("ErrorDialog.MSG2", "个警告"); + zhcn.put("ReportDialog.MSG", "EduMIPS64 致命错误!
请通过在 GitHub 上建立一个新 Issue并附上以下文本,或者通过发送电子邮件到bugs@edumips.org来帮助开发人员。"); + zhcn.put("ReportDialog.BUTTON", "关闭"); + zhcn.put("DIVZERO.Message", "除以零"); + zhcn.put("INTOVERFLOW.Message", "整数溢出"); + zhcn.put("FPOVERFLOW.Message", "浮点溢出"); + zhcn.put("FPUNDERFLOW.Message", "浮点下溢"); + zhcn.put("FPINVALID.Message", "浮点无效操作"); + zhcn.put("FPDIVBYZERO.Message", "浮点除以零"); + zhcn.put("NOOPENMODE", "没有指定打开文件的模式(读/写)"); + zhcn.put("WRITETOSTDIN", "试图写入标准输入"); + zhcn.put("FILENOTOPENED", "文件描述符无效。可能文件没有正确打开"); + zhcn.put("OUTOFMEMORY", "写(或读)操作导致无效的内存访问"); + zhcn.put("OUTOFMEMORY_PARSER", "输入文件中的数据超过了EduMIPS64的内存"); + zhcn.put("OUTOFINSTRUCTIONMEMORY", "指令内存耗尽"); + zhcn.put("READFROMSTDOUT", "试图从标准输出(或标准错误)读取"); + zhcn.put("OPENREADANDCREATE", "试图以读模式打开一个不存在的文件(O_CREAT在读或读/写模式下不起作用)"); + zhcn.put("INPUTNOTEXCEED", "输入不能超过"); + zhcn.put("CHARACTERS", "个字符"); + zhcn.put("ENTERINPUT", "请输入您的文本"); + zhcn.put("INPUT", "输入"); + zhcn.put("IOEXCEPTION", "I/O 错误"); + zhcn.put("HT.Options", "选项:"); + zhcn.put("HT.MissingFile", "错误:缺少文件名。"); + zhcn.put("HT.UnrecognizedArgs", "错误:无法识别的参数"); + zhcn.put("HT.MultipleFile", "错误:-f只能使用一次。"); + zhcn.put("CLEAR", "清除"); + zhcn.put("DATA", "数据"); + zhcn.put("HELPDIR", "/docs/user/zh"); + zhcn.put("NEGADDRERR", "指令中的负内存地址错误"); + zhcn.put("ALIGNERR", "指令中的对齐错误"); + zhcn.put("THEADDRESS", "该地址"); + zhcn.put("ISNOTALIGNED", "没有对齐到"); + zhcn.put("RESTART_FONT", "请重新启动模拟器以使用新字体。"); + zhcn.put("NO_MASK_AND_TERMINATE", "请在屏蔽同步异常和同步异常终止程序之间只选择一个选项。"); + zhcn.put("FWD_RESET_WARNING", "更改转发设置将重置模拟。继续吗? "); + zhcn.put("CLI.RUN.EXE_END", "执行结束。执行了 %d 个步骤,用时 %d 毫秒 "); + zhcn.put("CLI.STEP.NUM", "我执行了%d个模拟步骤。 "); + zhcn.put("CLI.EXIT", "再见..."); + zhcn.put("CLI.WELCOME", "欢迎使用 EduMIPS64 命令行界面!"); + zhcn.put("CLI.FILE.LOADED", "加载了文件%s "); + zhcn.put("CLI.FILE.NOT.LOADED", "无法加载文件:%s "); + zhcn.put("CLI.FILE.CANT.LOAD", "系统正在执行中,完成当前程序后再运行新程序 "); + zhcn.put("CLI.DINERO.CANT.WRITE", "在程序执行之前不能写入此输出。 "); + zhcn.put("CLI.FILE.NOT.FOUND", "找不到提供的文件,请检查位置并重试。 "); + zhcn.put("CLI.IO.ERROR", "写入文件时发生错误,请重试。 "); + zhcn.put("CLI.CONFIG.HEADER", "配置值 "); + zhcn.put("CLI.STEP.POSITIVE", "步骤必须是正数 "); + zhcn.put("CLI.CPU.NOT.RUNNABLE", "CPU在状态下不可运行: "); + zhcn.put("CLI.PARSE.ERROR", "无法解析文件,发现错误: "); + zhcn.put("CLI.DINERO.SAVE", "文件已保存!位置:"); + zhcn.put("LOG.HEADLESS_MSG", "无法在无头环境中启动 GUI。"); + zhcn.put("CLI.REG.WARN", "寄存器编号从 0 开始,有效值为 0-31。"); + zhcn.put("CLI.NOT.RUNNABLE.LOAD.FILE", "加载文件以使 CPU 可运行。尝试 load --help"); + zhcn.put("CLI.RUN.EXE_START", "开始执行。"); + zhcn.put("CLI.RUNNING", "运行中"); + zhcn.put("LOG.HEADLESS_MSG", "无法在无头环境中启动图形用户界面"); + languages.put("zhcn", zhcn); } public static String getString(String key) { diff --git a/src/main/resources/images/zhcn.png b/src/main/resources/images/zhcn.png new file mode 100644 index 000000000..f88b7ba13 Binary files /dev/null and b/src/main/resources/images/zhcn.png differ diff --git a/src/test/java/org/edumips64/CliRunnerTest.java b/src/test/java/org/edumips64/CliRunnerTest.java index 70b45ef76..b28cabe7f 100644 --- a/src/test/java/org/edumips64/CliRunnerTest.java +++ b/src/test/java/org/edumips64/CliRunnerTest.java @@ -123,6 +123,14 @@ public void printUsageIt() { assertFalse(os.toString().trim().isEmpty()); } + @Test + public void printUsageZh() { + OutputStream os = getSystemOut(); + Locale.setDefault(Locale.SIMPLIFIED_CHINESE); + new CommandLine(cli).execute("help"); + assertFalse(os.toString().trim().isEmpty()); + } + @Test public void printUsageShowEn() { OutputStream os = getSystemOut(); @@ -137,6 +145,13 @@ public void printUsageShowIt() { new CommandLine(cli).execute("show", "--help"); assertFalse(os.toString().trim().isEmpty()); } + @Test + public void printUsageMessageShowZh() { + OutputStream os = getSystemOut(); + Locale.setDefault(Locale.ITALIAN); + new CommandLine(cli).execute("show", "--help"); + assertFalse(os.toString().trim().isEmpty()); + } @Test public void printUsageStepEn() { @@ -154,6 +169,14 @@ public void printUsageStepIt() { } @Test + + public void printUsageStepZh() { + OutputStream os = getSystemOut(); + Locale.setDefault(Locale.SIMPLIFIED_CHINESE); + new CommandLine(cli).execute("step", "--help"); + assertFalse(os.toString().trim().isEmpty()); + } + public void printConfig() { new CommandLine(cli).execute("config"); } diff --git a/zh_CN.json b/zh_CN.json new file mode 100644 index 000000000..8f16ad0a6 --- /dev/null +++ b/zh_CN.json @@ -0,0 +1,33 @@ + { + "embeddedFonts": [ + "simsun.ttc" + ], + "fontsAlias": { + "stdFont": "simsun", + "stdBold": "simsun", + "stdItalic": "simsun", + "stdBoldItalic": "simsun", + "stdMono": "simsun", + "stdMonoBold": "simsun", + "stdMonoItalic": "simsun", + "stdMonoBoldItalic": "simsun", + "stdSans": "simsun", + "stdSansBold": "simsun", + "stdSansItalic": "simsun", + "stdSansBoldItalic": "simsun" + }, + "styles": [ + [ + "base", + { + "wordWrap": "CJK" + } + ], + [ + "literal", + { + "wordWrap": "None" + } + ] + ] +} \ No newline at end of file