sim: ppc: drop host endian configure option
[deliverable/binutils-gdb.git] / sim / erc32 / exec.c
index 5f1fc0c00ab87b54ea7fc6efacd2f3d15daa9677..d8a8c6c662b9fb075eaa019bfa411b83a1f1a0cc 100644 (file)
@@ -1,27 +1,25 @@
-/*
- * This file is part of SIS.
- * 
- * SIS, SPARC instruction simulator V1.8 Copyright (C) 1995 Jiri Gaisler,
- * European Space Agency
- * 
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- * 
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- * 
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- * 
- */
+/* This file is part of SIS (SPARC instruction simulator)
+
+   Copyright (C) 1995-2021 Free Software Foundation, Inc.
+   Contributed by Jiri Gaisler, European Space Agency
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This must come before any other includes.  */
+#include "defs.h"
 
 #include "sis.h"
-#include "end.h"
 #include <math.h>
 #include <stdio.h>
 
@@ -220,14 +218,14 @@ int ext_irl = 0;
 
 /* Forward declarations */
 
-static uint32  sub_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
-                               int32 result));
-static uint32  add_cc PARAMS ((uint32 psr, int32 operand1, int32 operand2,
-                               int32 result));
-static void    log_cc PARAMS ((int32 result, struct pstate *sregs));
-static int     fpexec PARAMS ((uint32 op3, uint32 rd, uint32 rs1, uint32 rs2,
-                               struct pstate *sregs));
-static int     chk_asi PARAMS ((struct pstate *sregs, uint32 *asi, uint32 op3));
+static uint32  sub_cc (uint32 psr, int32 operand1, int32 operand2,
+                       int32 result);
+static uint32  add_cc (uint32 psr, int32 operand1, int32 operand2,
+                       int32 result);
+static void    log_cc (int32 result, struct pstate *sregs);
+static int     fpexec (uint32 op3, uint32 rd, uint32 rs1, uint32 rs2,
+                       struct pstate *sregs);
+static int     chk_asi (struct pstate *sregs, uint32 *asi, uint32 op3);
 
 
 extern struct estate ebase;
@@ -238,11 +236,7 @@ extern uint32 errtt, errftt;
 #endif
 
 static uint32
-sub_cc(psr, operand1, operand2, result)
-    uint32          psr;
-    int32           operand1;
-    int32           operand2;
-    int32           result;
+sub_cc(uint32 psr, int32 operand1, int32 operand2, int32 result)
 {
     psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
     if (result)
@@ -253,15 +247,11 @@ sub_cc(psr, operand1, operand2, result)
                           (~operand1 & operand2 & result)) >> 10) & PSR_V);
     psr = (psr & ~PSR_C) | ((((~operand1 & operand2) |
                         ((~operand1 | operand2) & result)) >> 11) & PSR_C);
-    return (psr);
+    return psr;
 }
 
 uint32
-add_cc(psr, operand1, operand2, result)
-    uint32          psr;
-    int32           operand1;
-    int32           operand2;
-    int32           result;
+add_cc(uint32 psr, int32 operand1, int32 operand2, int32 result)
 {
     psr = ((psr & ~PSR_N) | ((result >> 8) & PSR_N));
     if (result)
@@ -272,13 +262,11 @@ add_cc(psr, operand1, operand2, result)
                          (~operand1 & ~operand2 & result)) >> 10) & PSR_V);
     psr = (psr & ~PSR_C) | ((((operand1 & operand2) |
                         ((operand1 | operand2) & ~result)) >> 11) & PSR_C);
-    return(psr);
+    return psr;
 }
 
 static void
-log_cc(result, sregs)
-    int32           result;
-    struct pstate  *sregs;
+log_cc(int32 result, struct pstate *sregs)
 {
     sregs->psr &= ~(PSR_CC);   /* Zero CC bits */
     sregs->psr = (sregs->psr | ((result >> 8) & PSR_N));
@@ -293,8 +281,8 @@ add32 (uint32 n1, uint32 n2, int *carry)
 {
   uint32 result = n1 + n2;
 
-  *carry = result < n1 || result < n1;
-  return(result);
+  *carry = result < n1 || result < n2;
+  return result;
 }
 
 /* Multiply two 32-bit integers.  */
@@ -371,9 +359,38 @@ div64 (uint32 n1_hi, uint32 n1_low, uint32 n2, uint32 *result, int msigned)
 }
 
 
+static int
+extract_short (uint32 data, uint32 address)
+{
+    return ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
+}
+
+static int
+extract_short_signed (uint32 data, uint32 address)
+{
+    uint32 tmp = ((data >> ((2 - (address & 2)) * 8)) & 0xffff);
+    if (tmp & 0x8000)
+        tmp |= 0xffff0000;
+    return tmp;
+}
+
+static int
+extract_byte (uint32 data, uint32 address)
+{
+    return ((data >> ((3 - (address & 3)) * 8)) & 0xff);
+}
+
+static int
+extract_byte_signed (uint32 data, uint32 address)
+{
+    uint32 tmp = ((data >> ((3 - (address & 3)) * 8)) & 0xff);
+    if (tmp & 0x80)
+        tmp |= 0xffffff00;
+    return tmp;
+}
+
 int
-dispatch_instruction(sregs)
-    struct pstate  *sregs;
+dispatch_instruction(struct pstate *sregs)
 {
 
     uint32          cwp, op, op2, op3, asi, rd, cond, rs1,
@@ -1078,7 +1095,8 @@ dispatch_instruction(sregs)
                    sregs->trap = TRAP_PRIVI;
                    break;
                }
-               sregs->psr = (rs1 ^ operand2) & 0x00f03fff;
+               sregs->psr = (sregs->psr & 0xff000000) |
+                       (rs1 ^ operand2) & 0x00f03fff;
                break;
            case WRWIM:
                if (!(sregs->psr & PSR_S)) {
@@ -1214,8 +1232,10 @@ dispatch_instruction(sregs)
                else
                    rdd = &(sregs->g[rd]);
            }
-           mexc = memory_read(asi, address, ddata, 3, &ws);
-           sregs->hold += ws * 2;
+           mexc = memory_read (asi, address, ddata, 2, &ws);
+           sregs->hold += ws;
+           mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
+           sregs->hold += ws;
            sregs->icnt = T_LDD;
            if (mexc) {
                sregs->trap = TRAP_DEXC;
@@ -1253,6 +1273,7 @@ dispatch_instruction(sregs)
                sregs->trap = TRAP_DEXC;
                break;
            }
+           data = extract_byte (data, address);
            *rdd = data;
            data = 0x0ff;
            mexc = memory_write(asi, address, &data, 0, &ws);
@@ -1275,8 +1296,10 @@ dispatch_instruction(sregs)
                sregs->trap = TRAP_DEXC;
                break;
            }
-           if ((op3 == LDSB) && (data & 0x80))
-               data |= 0xffffff00;
+           if (op3 == LDSB)
+               data = extract_byte_signed (data, address);
+           else
+               data = extract_byte (data, address);
            *rdd = data;
            break;
        case LDSHA:
@@ -1294,8 +1317,10 @@ dispatch_instruction(sregs)
                sregs->trap = TRAP_DEXC;
                break;
            }
-           if ((op3 == LDSH) && (data & 0x8000))
-               data |= 0xffff0000;
+           if (op3 == LDSH)
+               data = extract_short_signed (data, address);
+           else
+               data = extract_short (data, address);
            *rdd = data;
            break;
        case LDF:
@@ -1338,8 +1363,10 @@ dispatch_instruction(sregs)
                    ((sregs->frs2 >> 1) == (rd >> 1)))
                    sregs->fhold += (sregs->ftime - ebase.simtime);
            }
-           mexc = memory_read(asi, address, ddata, 3, &ws);
-           sregs->hold += ws * 2;
+           mexc = memory_read (asi, address, ddata, 2, &ws);
+           sregs->hold += ws;
+           mexc |= memory_read (asi, address+4, &ddata[1], 2, &ws);
+           sregs->hold += ws;
            sregs->icnt = T_LDD;
            if (mexc) {
                sregs->trap = TRAP_DEXC;
@@ -1584,7 +1611,7 @@ dispatch_instruction(sregs)
        sregs->pc = pc;
        sregs->npc = npc;
     }
-    return (0);
+    return 0;
 }
 
 #define T_FABSs                2
@@ -1635,9 +1662,7 @@ dispatch_instruction(sregs)
 
 
 static int
-fpexec(op3, rd, rs1, rs2, sregs)
-    uint32          op3, rd, rs1, rs2;
-    struct pstate  *sregs;
+fpexec(uint32 op3, uint32 rd, uint32 rs1, uint32 rs2, struct pstate *sregs)
 {
     uint32          opf, tem, accex;
     int32           fcc;
@@ -1646,11 +1671,11 @@ fpexec(op3, rd, rs1, rs2, sregs)
     if (sregs->fpstate == FP_EXC_MODE) {
        sregs->fsr = (sregs->fsr & ~FSR_TT) | FP_SEQ_ERR;
        sregs->fpstate = FP_EXC_PE;
-       return (0);
+       return 0;
     }
     if (sregs->fpstate == FP_EXC_PE) {
        sregs->fpstate = FP_EXC_MODE;
-       return (TRAP_FPEXC);
+       return TRAP_FPEXC;
     }
     opf = (sregs->inst >> 5) & 0x1ff;
 
@@ -1692,11 +1717,11 @@ fpexec(op3, rd, rs1, rs2, sregs)
     /* SPARC is big-endian - swap double floats if host is little-endian */
     /* This is ugly - I know ... */
 
-    /* FIXME: should use (CURRENT_HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
+    /* FIXME: should use (HOST_BYTE_ORDER == CURRENT_TARGET_BYTE_ORDER)
        but what about machines where float values are different endianness
        from integer values? */
 
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     rs1 &= 0x1f;
     switch (opf) {
        case FADDd:
@@ -1713,6 +1738,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
            sregs->fdp[rs2 | 1] = sregs->fs[rs2 & ~1];
            sregs->fdp[rs2 & ~1] = sregs->fs[rs2 | 1];
     default:
+      break;
     }
 #endif
 
@@ -1873,7 +1899,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
 
     accex = get_accex();
 
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     switch (opf) {
     case FADDd:
     case FDIVd:
@@ -1885,6 +1911,7 @@ fpexec(op3, rd, rs1, rs2, sregs)
        sregs->fs[rd & ~1] = sregs->fdp[rd | 1];
        sregs->fs[rd | 1] = sregs->fdp[rd & ~1];
     default:
+      break;
     }
 #endif
     if (sregs->fpstate == FP_EXC_PE) {
@@ -1908,31 +1935,27 @@ fpexec(op3, rd, rs1, rs2, sregs)
     }
     clear_accex();
 
-    return (0);
+    return 0;
 
 
 }
 
 static int
-chk_asi(sregs, asi, op3)
-    struct pstate  *sregs;
-    uint32 *asi, op3;
-
+chk_asi(struct pstate *sregs, uint32 *asi, uint32 op3)
 {
     if (!(sregs->psr & PSR_S)) {
        sregs->trap = TRAP_PRIVI;
-       return (0);
+       return 0;
     } else if (sregs->inst & INST_I) {
        sregs->trap = TRAP_UNIMP;
-       return (0);
+       return 0;
     } else
        *asi = (sregs->inst >> 5) & 0x0ff;
-    return(1);
+    return 1;
 }
 
 int
-execute_trap(sregs)
-    struct pstate  *sregs;
+execute_trap(struct pstate *sregs)
 {
     int32           cwp;
 
@@ -1941,11 +1964,11 @@ execute_trap(sregs)
        sregs->npc = 4;
        sregs->trap = 0;
     } else if (sregs->trap == 257) {
-           return (ERROR);
+           return ERROR;
     } else {
 
        if ((sregs->psr & PSR_ET) == 0)
-           return (ERROR);
+           return ERROR;
 
        sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
        sregs->trap = 0;
@@ -1972,15 +1995,14 @@ execute_trap(sregs)
     }
 
 
-    return (0);
+    return 0;
 
 }
 
 extern struct irqcell irqarr[16];
 
 int
-check_interrupts(sregs)
-    struct pstate  *sregs;
+check_interrupts(struct pstate *sregs)
 {
 #ifdef ERRINJ
     if (errtt) {
@@ -1995,21 +2017,20 @@ check_interrupts(sregs)
        if (sregs->trap == 0) {
            sregs->trap = 16 + ext_irl;
            irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
-           return(1);
+           return 1;
        }
     }
-    return(0);
+    return 0;
 }
 
 void
-init_regs(sregs)
-    struct pstate  *sregs;
+init_regs(struct pstate *sregs)
 {
     sregs->pc = 0;
     sregs->npc = 4;
     sregs->trap = 0;
     sregs->psr &= 0x00f03fdf;
-    sregs->psr |= 0x080;       /* Set supervisor bit */
+    sregs->psr |= 0x11000080;  /* Set supervisor bit */
     sregs->breakpoint = 0;
     sregs->annul = 0;
     sregs->fpstate = FP_EXE_MODE;
@@ -2019,7 +2040,7 @@ init_regs(sregs)
     sregs->err_mode = 0;
     ext_irl = 0;
     sregs->g[0] = 0;
-#ifdef HOST_LITTLE_ENDIAN_FLOAT
+#ifdef HOST_LITTLE_ENDIAN
     sregs->fdp = (float32 *) sregs->fd;
     sregs->fsi = (int32 *) sregs->fs;
 #else
This page took 0.029041 seconds and 4 git commands to generate.