1/* Tests some basic fpu instructions. 2 3 Copyright (C) 2019-2023 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18# mach: or1k 19# output: report(0x400921f9);\n 20# output: report(0xf01b866e);\n 21# output: report(0x4005bf09);\n 22# output: report(0x95aaf790);\n 23# output: report(0x00000000);\n 24# output: report(0x00001234);\n 25# output: \n 26# output: report(0x40b23400);\n 27# output: report(0x00000000);\n 28# output: report(0x40b23400);\n 29# output: report(0x00000000);\n 30# output: \n 31# output: report(0x40177081);\n 32# output: report(0xc2e33eff);\n 33# output: report(0x400921f9);\n 34# output: report(0xf01b866e);\n 35# output: \n 36# output: report(0x40211456);\n 37# output: report(0x587dfabf);\n 38# output: report(0x400921f9);\n 39# output: report(0xf01b866d);\n 40# output: \n 41# output: report(0x00000001);\n 42# output: \n 43# output: WARNING: ignoring fpu error caught in fast mode.\n 44# output: report(0x00000000);\n 45# output: \n 46# output: exit(0)\n 47 48#include "or1k-asm-test-helpers.h" 49 50 STANDARD_TEST_ENVIRONMENT 51 52 .section .exception_vectors 53 54 /* Floating point exception. */ 55 .org 0xd00 56 57 /* The handling is a bit dubious at present. We just patch the 58 instruction with l.nop and restart. This will go wrong in branch 59 delay slots. But we don't have those in this test. */ 60 l.addi r1, r1, -EXCEPTION_STACK_SKIP_SIZE 61 PUSH r2 62 PUSH r3 63 /* Save the address of the instruction that caused the problem. */ 64 MOVE_FROM_SPR r2, SPR_EPCR_BASE 65 LOAD_IMMEDIATE r3, 0x15000000 /* Opcode for l.nop */ 66 l.sw -4(r2), r3 67 POP r3 68 POP r2 69 l.addi r1, r1, EXCEPTION_STACK_SKIP_SIZE 70 l.rfe 71 72 .section .data 73 .align 4 74 .type pi, @object 75 .size pi, 8 76anchor: 77pi: 78 .double 3.14159 79 80 .type e, @object 81 .size e, 8 82e: 83 .double 2.71828 84 85 .type large, @object 86 .size large, 8 87large: 88 .long 0 89 .long 0x1234 90 91 .section .text 92start_tests: 93 PUSH LINK_REGISTER_R9 94 95 /* Test lf.itof.d int to double conversion. Setting up: 96 * r11 pointer to data 97 * r12,r13 pi as double 98 * r14,r15 e as double 99 * r16,r17 a long long 100 */ 101 l.ori r11, r0, ha(anchor) 102 l.addi r11, r11, lo(anchor) 103 l.lwz r12, 0(r11) 104 l.lwz r13, 4(r11) 105 106 l.lwz r14, 8(r11) 107 l.lwz r15, 12(r11) 108 109 l.lwz r16, 16(r11) 110 l.lwz r18, 20(r11) 111 112 /* Output to ensure we loaded it correctly. */ 113 REPORT_REG_TO_CONSOLE r12 114 REPORT_REG_TO_CONSOLE r13 115 116 REPORT_REG_TO_CONSOLE r14 117 REPORT_REG_TO_CONSOLE r15 118 119 REPORT_REG_TO_CONSOLE r16 120 REPORT_REG_TO_CONSOLE r18 121 PRINT_NEWLINE_TO_CONSOLE 122 123 /* Convert the big long to a double. */ 124 lf.itof.d r16,r18, r16,r18 125 REPORT_REG_TO_CONSOLE r16 126 REPORT_REG_TO_CONSOLE r18 127 128 /* Convert the double back to a long, it should match before. */ 129 lf.ftoi.d r16,r18, r16,r18 130 lf.itof.d r16,r18, r16,r18 131 132 REPORT_REG_TO_CONSOLE r16 133 REPORT_REG_TO_CONSOLE r18 134 135 PRINT_NEWLINE_TO_CONSOLE 136 137 /* Add and subtract some double values. */ 138 lf.add.d r12,r13, r12,r13, r14,r15 139 REPORT_REG_TO_CONSOLE r12 140 REPORT_REG_TO_CONSOLE r13 141 142 lf.sub.d r12,r13, r12,r13, r14,r15 143 REPORT_REG_TO_CONSOLE r12 144 REPORT_REG_TO_CONSOLE r13 145 PRINT_NEWLINE_TO_CONSOLE 146 147 /* Multiply and divide double values. */ 148 lf.mul.d r12,r13, r12,r13, r14,r15 149 REPORT_REG_TO_CONSOLE r12 150 REPORT_REG_TO_CONSOLE r13 151 152 lf.div.d r12,r13, r12,r13, r14,r15 153 REPORT_REG_TO_CONSOLE r12 154 REPORT_REG_TO_CONSOLE r13 155 PRINT_NEWLINE_TO_CONSOLE 156 157 /* Test lf.sfge.s set flag if r6 >= r10. */ 158 lf.sfge.d r12,r13, r14,r15 159 MOVE_FROM_SPR r2, SPR_SR 160 REPORT_BIT_TO_CONSOLE r2, SPR_SR_F 161 PRINT_NEWLINE_TO_CONSOLE 162 163 /* Test raising an exception by dividing by 0. */ 164 MOVE_FROM_SPR r2, SPR_FPCSR 165 l.ori r2, r2, 0x1 166 MOVE_TO_SPR SPR_FPCSR, r2 167div0: lf.div.d r2,r3, r12,r13, r0,r1 168 REPORT_EXCEPTION div0 169 PRINT_NEWLINE_TO_CONSOLE 170 171 POP LINK_REGISTER_R9 172 RETURN_TO_LINK_REGISTER_R9 173