1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef NATIVE_BRIDGE_SUPPORT_RISCV64_GUEST_STATE_GUEST_STATE_CPU_STATE_H_ 18 #define NATIVE_BRIDGE_SUPPORT_RISCV64_GUEST_STATE_GUEST_STATE_CPU_STATE_H_ 19 20 namespace berberis { 21 22 using GuestAddr = uintptr_t; 23 using Reservation = uint64_t; 24 25 struct CPUState { 26 // x0 to x31. 27 uint64_t x[32]; 28 // f0 to f31. We are using uint64_t because C++ may change values of NaN when they are passed from 29 // or to function and RISC-V uses NaN-boxing which would make things problematic. 30 uint64_t f[32]; 31 // v0 to v32. We only support 128bit vectors for now. 32 alignas(16) __uint128_t v[32]; 33 34 GuestAddr insn_addr; 35 36 GuestAddr reservation_address; 37 Reservation reservation_value; 38 39 // Technically only 9 bits are defined: sign bit and 8 low bits. 40 // But for performance reason it's easier to keep full 64bits in this variable. 41 uint64_t vtype; 42 // This register usually contains zero and each vector instruction would reset it to zero. 43 // But it's allowed to change it and if that happens we are supposed to support it. 44 uint8_t vstart; 45 // This register is usually set to process full 128 bits set of SIMD data. 46 // But it's allowed to change it and if that happens we are supposed to support it. 47 uint8_t vl; 48 // Only 3 bits are defined but we allocate full byte to simplify implementation. 49 uint8_t vcsr; 50 // RISC-V has five rounding modes, while x86-64 has only four. 51 // 52 // Extra rounding mode (RMM in RISC-V documentation) is emulated but requires the use of 53 // FE_TOWARDZERO mode for correct work. 54 // 55 // Additionally RISC-V implementation is supposed to support three “illegal” rounding modes and 56 // when they are selected all instructions which use rounding mode trigger “undefined instruction” 57 // exception. 58 // 59 // For simplicity we always keep full rounding mode (3 bits) in the frm field and set host 60 // rounding mode to appropriate one. 61 // 62 // Exceptions, on the other hand, couldn't be stored here efficiently, instead we rely on the fact 63 // that x86-64 implements all five exceptions that RISC-V needs (and more). 64 uint8_t frm; 65 }; 66 67 } 68 #endif // NATIVE_BRIDGE_SUPPORT_RISCV64_GUEST_STATE_GUEST_STATE_CPU_STATE_H_