qemu/target/hppa/helper.c
<<
>>
Prefs
   1/*
   2 *  HPPA emulation cpu helpers for qemu.
   3 *
   4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21
  22#include "cpu.h"
  23#include "exec/exec-all.h"
  24#include "fpu/softfloat.h"
  25#include "exec/helper-proto.h"
  26
  27target_ulong cpu_hppa_get_psw(CPUHPPAState *env)
  28{
  29    target_ulong psw;
  30
  31    /* Fold carry bits down to 8 consecutive bits.  */
  32    /* ??? Needs tweaking for hppa64.  */
  33    /* .......b...c...d...e...f...g...h */
  34    psw = (env->psw_cb >> 4) & 0x01111111;
  35    /* .......b..bc..cd..de..ef..fg..gh */
  36    psw |= psw >> 3;
  37    /* .............bcd............efgh */
  38    psw |= (psw >> 6) & 0x000f000f;
  39    /* .........................bcdefgh */
  40    psw |= (psw >> 12) & 0xf;
  41    psw |= env->psw_cb_msb << 7;
  42    psw <<= 8;
  43
  44    psw |= env->psw_n << 21;
  45    psw |= (env->psw_v < 0) << 17;
  46
  47    return psw;
  48}
  49
  50void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong psw)
  51{
  52    target_ulong cb = 0;
  53
  54    env->psw_n = (psw >> 21) & 1;
  55    env->psw_v = -((psw >> 17) & 1);
  56    env->psw_cb_msb = (psw >> 15) & 1;
  57
  58    cb |= ((psw >> 14) & 1) << 28;
  59    cb |= ((psw >> 13) & 1) << 24;
  60    cb |= ((psw >> 12) & 1) << 20;
  61    cb |= ((psw >> 11) & 1) << 16;
  62    cb |= ((psw >> 10) & 1) << 12;
  63    cb |= ((psw >>  9) & 1) <<  8;
  64    cb |= ((psw >>  8) & 1) <<  4;
  65    env->psw_cb = cb;
  66}
  67
  68int hppa_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
  69                              int rw, int mmu_idx)
  70{
  71    HPPACPU *cpu = HPPA_CPU(cs);
  72
  73    cs->exception_index = EXCP_SIGSEGV;
  74    cpu->env.ior = address;
  75    return 1;
  76}
  77
  78void hppa_cpu_do_interrupt(CPUState *cs)
  79{
  80    HPPACPU *cpu = HPPA_CPU(cs);
  81    CPUHPPAState *env = &cpu->env;
  82    int i = cs->exception_index;
  83
  84    if (qemu_loglevel_mask(CPU_LOG_INT)) {
  85        static int count;
  86        const char *name = "<unknown>";
  87
  88        switch (i) {
  89        case EXCP_SYSCALL:
  90            name = "syscall";
  91            break;
  92        case EXCP_SIGSEGV:
  93            name = "sigsegv";
  94            break;
  95        case EXCP_SIGILL:
  96            name = "sigill";
  97            break;
  98        case EXCP_SIGFPE:
  99            name = "sigfpe";
 100            break;
 101        }
 102        qemu_log("INT %6d: %s ia_f=" TARGET_FMT_lx "\n",
 103                 ++count, name, env->iaoq_f);
 104    }
 105    cs->exception_index = -1;
 106}
 107
 108bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 109{
 110    abort();
 111    return false;
 112}
 113
 114void hppa_cpu_dump_state(CPUState *cs, FILE *f,
 115                         fprintf_function cpu_fprintf, int flags)
 116{
 117    HPPACPU *cpu = HPPA_CPU(cs);
 118    CPUHPPAState *env = &cpu->env;
 119    int i;
 120
 121    cpu_fprintf(f, "IA_F " TARGET_FMT_lx
 122                   " IA_B " TARGET_FMT_lx
 123                   " PSW  " TARGET_FMT_lx
 124                   " [N:" TARGET_FMT_ld " V:%d"
 125                   " CB:" TARGET_FMT_lx "]\n              ",
 126                env->iaoq_f, env->iaoq_b, cpu_hppa_get_psw(env),
 127                env->psw_n, env->psw_v < 0,
 128                ((env->psw_cb >> 4) & 0x01111111) | (env->psw_cb_msb << 28));
 129    for (i = 1; i < 32; i++) {
 130        cpu_fprintf(f, "GR%02d " TARGET_FMT_lx " ", i, env->gr[i]);
 131        if ((i % 4) == 3) {
 132            cpu_fprintf(f, "\n");
 133        }
 134    }
 135
 136    /* ??? FR */
 137}
 138