| /* |
| * Copyright (c) 2013 The Native Client Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #define JUMP_MASK $t6 |
| |
| /* |
| * Rounding mode control field is bits [1:0] in FCSR. |
| * This function takes the two-bit value and sets bits [1:0]. |
| * |
| * The bit patterns for MIPS are: |
| * 0b00 Round to Nearest (RN) mode |
| * 0b10 Round towards Plus Infinity (RP) mode |
| * 0b11 Round towards Minus Infinity (RM) mode |
| * 0b01 Round towards Zero (RZ) mode |
| */ |
| .text |
| .p2align 4 |
| set_rounding_control_field: |
| /* LLVM's MipsAsmParser can't parse cfc1 $v0, $31, |
| * So try to use .word. Using .word we can encode |
| * the instruction, but the validator rejects this |
| * instruction. Eventually we may make a syscall to enable |
| * setting the control word, so that the untrusted code |
| * won't be responsible for this. |
| */ |
| #if defined(__clang__) |
| # .word 0x4442f800 |
| #else |
| cfc1 $v0, $31 /* fcsr */ |
| #endif |
| li $t1, 0xfffffffc |
| and $v0, $v0, $t1 |
| or $v0, $v0, $a0 |
| #if defined(__clang__) |
| # .word 0x44c2f800 |
| #else |
| ctc1 $v0, $31 /* fcsr */ |
| #endif |
| nop /* Force return sequence to next bundle. */ |
| |
| and $ra, $ra, JUMP_MASK |
| jr $ra |
| nop |
| |
| .p2align 4 |
| .globl set_round_toward_nearest |
| set_round_toward_nearest: |
| li $a0, 0 |
| j set_rounding_control_field |
| |
| .p2align 4 |
| .globl set_round_toward_plus_infinity |
| set_round_toward_plus_infinity: |
| li $a0, 2 |
| j set_rounding_control_field |
| |
| .p2align 4 |
| .globl set_round_toward_minus_infinity |
| set_round_toward_minus_infinity: |
| li $a0, 3 |
| j set_rounding_control_field |
| |
| .p2align 4 |
| .globl set_round_toward_zero |
| set_round_toward_zero: |
| li $a0, 1 |
| j set_rounding_control_field |