xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/armvirt.c (revision 4b169a6ba595ae283ca507b26b15fdff40495b1c)
198b9484cSchristos /*  armvirt.c -- ARMulator virtual memory interace:  ARM6 Instruction Emulator.
298b9484cSchristos     Copyright (C) 1994 Advanced RISC Machines Ltd.
398b9484cSchristos 
498b9484cSchristos     This program is free software; you can redistribute it and/or modify
598b9484cSchristos     it under the terms of the GNU General Public License as published by
6a2e2270fSchristos     the Free Software Foundation; either version 3 of the License, or
798b9484cSchristos     (at your option) any later version.
898b9484cSchristos 
998b9484cSchristos     This program is distributed in the hope that it will be useful,
1098b9484cSchristos     but WITHOUT ANY WARRANTY; without even the implied warranty of
1198b9484cSchristos     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1298b9484cSchristos     GNU General Public License for more details.
1398b9484cSchristos 
1498b9484cSchristos     You should have received a copy of the GNU General Public License
15a2e2270fSchristos     along with this program; if not, see <http://www.gnu.org/licenses/>. */
1698b9484cSchristos 
1798b9484cSchristos /* This file contains a complete ARMulator memory model, modelling a
1898b9484cSchristos    "virtual memory" system. A much simpler model can be found in armfast.c,
1998b9484cSchristos    and that model goes faster too, but has a fixed amount of memory. This
2098b9484cSchristos    model's memory has 64K pages, allocated on demand from a 64K entry page
2198b9484cSchristos    table. The routines PutWord and GetWord implement this. Pages are never
2298b9484cSchristos    freed as they might be needed again. A single area of memory may be
2398b9484cSchristos    defined to generate aborts.  */
2498b9484cSchristos 
25*4b169a6bSchristos /* This must come before any other includes.  */
26*4b169a6bSchristos #include "defs.h"
27*4b169a6bSchristos 
2898b9484cSchristos #include "armos.h"
2998b9484cSchristos #include "armdefs.h"
3098b9484cSchristos #include "ansidecl.h"
3198b9484cSchristos 
3298b9484cSchristos #ifdef VALIDATE			/* for running the validate suite */
3398b9484cSchristos #define TUBE 48 * 1024 * 1024	/* write a char on the screen */
3498b9484cSchristos #define ABORTS 1
3598b9484cSchristos #endif
3698b9484cSchristos 
3798b9484cSchristos /* #define ABORTS */
3898b9484cSchristos 
3998b9484cSchristos #ifdef ABORTS			/* the memory system will abort */
4098b9484cSchristos /* For the old test suite Abort between 32 Kbytes and 32 Mbytes
4198b9484cSchristos    For the new test suite Abort between 8 Mbytes and 26 Mbytes */
4298b9484cSchristos /* #define LOWABORT 32 * 1024
4398b9484cSchristos #define HIGHABORT 32 * 1024 * 1024 */
4498b9484cSchristos #define LOWABORT 8 * 1024 * 1024
4598b9484cSchristos #define HIGHABORT 26 * 1024 * 1024
4698b9484cSchristos 
4798b9484cSchristos #endif
4898b9484cSchristos 
49*4b169a6bSchristos #undef PAGESIZE			/* Cleanup system headers.  */
5098b9484cSchristos #define NUMPAGES 64 * 1024
5198b9484cSchristos #define PAGESIZE 64 * 1024
5298b9484cSchristos #define PAGEBITS 16
5398b9484cSchristos #define OFFSETBITS 0xffff
5498b9484cSchristos 
5598b9484cSchristos int SWI_vector_installed = FALSE;
5698b9484cSchristos 
5798b9484cSchristos /***************************************************************************\
5898b9484cSchristos *        Get a Word from Virtual Memory, maybe allocating the page          *
5998b9484cSchristos \***************************************************************************/
6098b9484cSchristos 
6198b9484cSchristos static ARMword
GetWord(ARMul_State * state,ARMword address,int check)6298b9484cSchristos GetWord (ARMul_State * state, ARMword address, int check)
6398b9484cSchristos {
6498b9484cSchristos   ARMword page;
6598b9484cSchristos   ARMword offset;
6698b9484cSchristos   ARMword **pagetable;
6798b9484cSchristos   ARMword *pageptr;
6898b9484cSchristos 
6998b9484cSchristos   if (check && state->is_XScale)
7098b9484cSchristos     XScale_check_memacc (state, &address, 0);
7198b9484cSchristos 
7298b9484cSchristos   page = address >> PAGEBITS;
7398b9484cSchristos   offset = (address & OFFSETBITS) >> 2;
7498b9484cSchristos   pagetable = (ARMword **) state->MemDataPtr;
7598b9484cSchristos   pageptr = *(pagetable + page);
7698b9484cSchristos 
7798b9484cSchristos   if (pageptr == NULL)
7898b9484cSchristos     {
7998b9484cSchristos       pageptr = (ARMword *) malloc (PAGESIZE);
8098b9484cSchristos 
8198b9484cSchristos       if (pageptr == NULL)
8298b9484cSchristos 	{
8398b9484cSchristos 	  perror ("ARMulator can't allocate VM page");
8498b9484cSchristos 	  exit (12);
8598b9484cSchristos 	}
8698b9484cSchristos 
8798b9484cSchristos       *(pagetable + page) = pageptr;
8898b9484cSchristos     }
8998b9484cSchristos 
9098b9484cSchristos   return *(pageptr + offset);
9198b9484cSchristos }
9298b9484cSchristos 
9398b9484cSchristos /***************************************************************************\
9498b9484cSchristos *        Put a Word into Virtual Memory, maybe allocating the page          *
9598b9484cSchristos \***************************************************************************/
9698b9484cSchristos 
9798b9484cSchristos static void
PutWord(ARMul_State * state,ARMword address,ARMword data,int check)9898b9484cSchristos PutWord (ARMul_State * state, ARMword address, ARMword data, int check)
9998b9484cSchristos {
10098b9484cSchristos   ARMword page;
10198b9484cSchristos   ARMword offset;
10298b9484cSchristos   ARMword **pagetable;
10398b9484cSchristos   ARMword *pageptr;
10498b9484cSchristos 
10598b9484cSchristos   if (check && state->is_XScale)
10698b9484cSchristos     XScale_check_memacc (state, &address, 1);
10798b9484cSchristos 
10898b9484cSchristos   page = address >> PAGEBITS;
10998b9484cSchristos   offset = (address & OFFSETBITS) >> 2;
11098b9484cSchristos   pagetable = (ARMword **) state->MemDataPtr;
11198b9484cSchristos   pageptr = *(pagetable + page);
11298b9484cSchristos 
11398b9484cSchristos   if (pageptr == NULL)
11498b9484cSchristos     {
11598b9484cSchristos       pageptr = (ARMword *) malloc (PAGESIZE);
11698b9484cSchristos       if (pageptr == NULL)
11798b9484cSchristos 	{
11898b9484cSchristos 	  perror ("ARMulator can't allocate VM page");
11998b9484cSchristos 	  exit (13);
12098b9484cSchristos 	}
12198b9484cSchristos 
12298b9484cSchristos       *(pagetable + page) = pageptr;
12398b9484cSchristos     }
12498b9484cSchristos 
12598b9484cSchristos   if (address == 0x8)
12698b9484cSchristos     SWI_vector_installed = TRUE;
12798b9484cSchristos 
12898b9484cSchristos   *(pageptr + offset) = data;
12998b9484cSchristos }
13098b9484cSchristos 
13198b9484cSchristos /***************************************************************************\
13298b9484cSchristos *                      Initialise the memory interface                      *
13398b9484cSchristos \***************************************************************************/
13498b9484cSchristos 
13598b9484cSchristos unsigned
ARMul_MemoryInit(ARMul_State * state,unsigned long initmemsize)13698b9484cSchristos ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize)
13798b9484cSchristos {
13898b9484cSchristos   ARMword **pagetable;
13998b9484cSchristos   unsigned page;
14098b9484cSchristos 
14198b9484cSchristos   if (initmemsize)
14298b9484cSchristos     state->MemSize = initmemsize;
14398b9484cSchristos 
14498b9484cSchristos   pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES);
14598b9484cSchristos 
14698b9484cSchristos   if (pagetable == NULL)
14798b9484cSchristos     return FALSE;
14898b9484cSchristos 
14998b9484cSchristos   for (page = 0; page < NUMPAGES; page++)
15098b9484cSchristos     *(pagetable + page) = NULL;
15198b9484cSchristos 
15298b9484cSchristos   state->MemDataPtr = (unsigned char *) pagetable;
15398b9484cSchristos 
15498b9484cSchristos   ARMul_ConsolePrint (state, ", 4 Gb memory");
15598b9484cSchristos 
15698b9484cSchristos   return TRUE;
15798b9484cSchristos }
15898b9484cSchristos 
15998b9484cSchristos /***************************************************************************\
16098b9484cSchristos *                         Remove the memory interface                       *
16198b9484cSchristos \***************************************************************************/
16298b9484cSchristos 
16398b9484cSchristos void
ARMul_MemoryExit(ARMul_State * state)16498b9484cSchristos ARMul_MemoryExit (ARMul_State * state)
16598b9484cSchristos {
16698b9484cSchristos   ARMword page;
16798b9484cSchristos   ARMword **pagetable;
16898b9484cSchristos   ARMword *pageptr;
16998b9484cSchristos 
17098b9484cSchristos   pagetable = (ARMword **) state->MemDataPtr;
17198b9484cSchristos   for (page = 0; page < NUMPAGES; page++)
17298b9484cSchristos     {
17398b9484cSchristos       pageptr = *(pagetable + page);
17498b9484cSchristos       if (pageptr != NULL)
17598b9484cSchristos 	free ((char *) pageptr);
17698b9484cSchristos     }
17798b9484cSchristos   free ((char *) pagetable);
17898b9484cSchristos   return;
17998b9484cSchristos }
18098b9484cSchristos 
18198b9484cSchristos /***************************************************************************\
18298b9484cSchristos *                   ReLoad Instruction                                     *
18398b9484cSchristos \***************************************************************************/
18498b9484cSchristos 
18598b9484cSchristos ARMword
ARMul_ReLoadInstr(ARMul_State * state,ARMword address,ARMword isize)18698b9484cSchristos ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
18798b9484cSchristos {
18898b9484cSchristos #ifdef ABORTS
18998b9484cSchristos   if (address >= LOWABORT && address < HIGHABORT)
19098b9484cSchristos     {
19198b9484cSchristos       ARMul_PREFETCHABORT (address);
19298b9484cSchristos       return ARMul_ABORTWORD;
19398b9484cSchristos     }
19498b9484cSchristos   else
19598b9484cSchristos     {
19698b9484cSchristos       ARMul_CLEARABORT;
19798b9484cSchristos     }
19898b9484cSchristos #endif
19998b9484cSchristos 
20098b9484cSchristos   if ((isize == 2) && (address & 0x2))
20198b9484cSchristos     {
20298b9484cSchristos       /* We return the next two halfwords: */
20398b9484cSchristos       ARMword lo = GetWord (state, address, FALSE);
20498b9484cSchristos       ARMword hi = GetWord (state, address + 4, FALSE);
20598b9484cSchristos 
20698b9484cSchristos       if (state->bigendSig == HIGH)
20798b9484cSchristos 	return (lo << 16) | (hi >> 16);
20898b9484cSchristos       else
20998b9484cSchristos 	return ((hi & 0xFFFF) << 16) | (lo >> 16);
21098b9484cSchristos     }
21198b9484cSchristos 
21298b9484cSchristos   return GetWord (state, address, TRUE);
21398b9484cSchristos }
21498b9484cSchristos 
21598b9484cSchristos /***************************************************************************\
21698b9484cSchristos *                   Load Instruction, Sequential Cycle                      *
21798b9484cSchristos \***************************************************************************/
21898b9484cSchristos 
ARMul_LoadInstrS(ARMul_State * state,ARMword address,ARMword isize)21998b9484cSchristos ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
22098b9484cSchristos {
22198b9484cSchristos   state->NumScycles++;
22298b9484cSchristos 
22398b9484cSchristos   return ARMul_ReLoadInstr (state, address, isize);
22498b9484cSchristos }
22598b9484cSchristos 
22698b9484cSchristos /***************************************************************************\
22798b9484cSchristos *                 Load Instruction, Non Sequential Cycle                    *
22898b9484cSchristos \***************************************************************************/
22998b9484cSchristos 
ARMul_LoadInstrN(ARMul_State * state,ARMword address,ARMword isize)23098b9484cSchristos ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
23198b9484cSchristos {
23298b9484cSchristos   state->NumNcycles++;
23398b9484cSchristos 
23498b9484cSchristos   return ARMul_ReLoadInstr (state, address, isize);
23598b9484cSchristos }
23698b9484cSchristos 
23798b9484cSchristos /***************************************************************************\
23898b9484cSchristos *                      Read Word (but don't tell anyone!)                   *
23998b9484cSchristos \***************************************************************************/
24098b9484cSchristos 
ARMul_ReadWord(ARMul_State * state,ARMword address)24198b9484cSchristos ARMword ARMul_ReadWord (ARMul_State * state, ARMword address)
24298b9484cSchristos {
24398b9484cSchristos #ifdef ABORTS
24498b9484cSchristos   if (address >= LOWABORT && address < HIGHABORT)
24598b9484cSchristos     {
24698b9484cSchristos       ARMul_DATAABORT (address);
24798b9484cSchristos       return ARMul_ABORTWORD;
24898b9484cSchristos     }
24998b9484cSchristos   else
25098b9484cSchristos     {
25198b9484cSchristos       ARMul_CLEARABORT;
25298b9484cSchristos     }
25398b9484cSchristos #endif
25498b9484cSchristos 
25598b9484cSchristos   return GetWord (state, address, TRUE);
25698b9484cSchristos }
25798b9484cSchristos 
25898b9484cSchristos /***************************************************************************\
25998b9484cSchristos *                        Load Word, Sequential Cycle                        *
26098b9484cSchristos \***************************************************************************/
26198b9484cSchristos 
ARMul_LoadWordS(ARMul_State * state,ARMword address)26298b9484cSchristos ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address)
26398b9484cSchristos {
26498b9484cSchristos   state->NumScycles++;
26598b9484cSchristos 
26698b9484cSchristos   return ARMul_ReadWord (state, address);
26798b9484cSchristos }
26898b9484cSchristos 
26998b9484cSchristos /***************************************************************************\
27098b9484cSchristos *                      Load Word, Non Sequential Cycle                      *
27198b9484cSchristos \***************************************************************************/
27298b9484cSchristos 
ARMul_LoadWordN(ARMul_State * state,ARMword address)27398b9484cSchristos ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address)
27498b9484cSchristos {
27598b9484cSchristos   state->NumNcycles++;
27698b9484cSchristos 
27798b9484cSchristos   return ARMul_ReadWord (state, address);
27898b9484cSchristos }
27998b9484cSchristos 
28098b9484cSchristos /***************************************************************************\
28198b9484cSchristos *                     Load Halfword, (Non Sequential Cycle)                 *
28298b9484cSchristos \***************************************************************************/
28398b9484cSchristos 
ARMul_LoadHalfWord(ARMul_State * state,ARMword address)28498b9484cSchristos ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
28598b9484cSchristos {
28698b9484cSchristos   ARMword temp, offset;
28798b9484cSchristos 
28898b9484cSchristos   state->NumNcycles++;
28998b9484cSchristos 
29098b9484cSchristos   temp = ARMul_ReadWord (state, address);
29198b9484cSchristos   offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;	/* bit offset into the word */
29298b9484cSchristos 
29398b9484cSchristos   return (temp >> offset) & 0xffff;
29498b9484cSchristos }
29598b9484cSchristos 
29698b9484cSchristos /***************************************************************************\
29798b9484cSchristos *                      Read Byte (but don't tell anyone!)                   *
29898b9484cSchristos \***************************************************************************/
29998b9484cSchristos 
ARMul_ReadByte(ARMul_State * state,ARMword address)30098b9484cSchristos ARMword ARMul_ReadByte (ARMul_State * state, ARMword address)
30198b9484cSchristos {
30298b9484cSchristos   ARMword temp, offset;
30398b9484cSchristos 
30498b9484cSchristos   temp = ARMul_ReadWord (state, address);
30598b9484cSchristos   offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;	/* bit offset into the word */
30698b9484cSchristos 
30798b9484cSchristos   return (temp >> offset & 0xffL);
30898b9484cSchristos }
30998b9484cSchristos 
31098b9484cSchristos /***************************************************************************\
31198b9484cSchristos *                     Load Byte, (Non Sequential Cycle)                     *
31298b9484cSchristos \***************************************************************************/
31398b9484cSchristos 
ARMul_LoadByte(ARMul_State * state,ARMword address)31498b9484cSchristos ARMword ARMul_LoadByte (ARMul_State * state, ARMword address)
31598b9484cSchristos {
31698b9484cSchristos   state->NumNcycles++;
31798b9484cSchristos 
31898b9484cSchristos   return ARMul_ReadByte (state, address);
31998b9484cSchristos }
32098b9484cSchristos 
32198b9484cSchristos /***************************************************************************\
32298b9484cSchristos *                     Write Word (but don't tell anyone!)                   *
32398b9484cSchristos \***************************************************************************/
32498b9484cSchristos 
32598b9484cSchristos void
ARMul_WriteWord(ARMul_State * state,ARMword address,ARMword data)32698b9484cSchristos ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
32798b9484cSchristos {
32898b9484cSchristos #ifdef ABORTS
32998b9484cSchristos   if (address >= LOWABORT && address < HIGHABORT)
33098b9484cSchristos     {
33198b9484cSchristos       ARMul_DATAABORT (address);
33298b9484cSchristos       return;
33398b9484cSchristos     }
33498b9484cSchristos   else
33598b9484cSchristos     {
33698b9484cSchristos       ARMul_CLEARABORT;
33798b9484cSchristos     }
33898b9484cSchristos #endif
33998b9484cSchristos 
34098b9484cSchristos   PutWord (state, address, data, TRUE);
34198b9484cSchristos }
34298b9484cSchristos 
34398b9484cSchristos /***************************************************************************\
34498b9484cSchristos *                       Store Word, Sequential Cycle                        *
34598b9484cSchristos \***************************************************************************/
34698b9484cSchristos 
34798b9484cSchristos void
ARMul_StoreWordS(ARMul_State * state,ARMword address,ARMword data)34898b9484cSchristos ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
34998b9484cSchristos {
35098b9484cSchristos   state->NumScycles++;
35198b9484cSchristos 
35298b9484cSchristos   ARMul_WriteWord (state, address, data);
35398b9484cSchristos }
35498b9484cSchristos 
35598b9484cSchristos /***************************************************************************\
35698b9484cSchristos *                       Store Word, Non Sequential Cycle                        *
35798b9484cSchristos \***************************************************************************/
35898b9484cSchristos 
35998b9484cSchristos void
ARMul_StoreWordN(ARMul_State * state,ARMword address,ARMword data)36098b9484cSchristos ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
36198b9484cSchristos {
36298b9484cSchristos   state->NumNcycles++;
36398b9484cSchristos 
36498b9484cSchristos   ARMul_WriteWord (state, address, data);
36598b9484cSchristos }
36698b9484cSchristos 
36798b9484cSchristos /***************************************************************************\
36898b9484cSchristos *                    Store HalfWord, (Non Sequential Cycle)                 *
36998b9484cSchristos \***************************************************************************/
37098b9484cSchristos 
37198b9484cSchristos void
ARMul_StoreHalfWord(ARMul_State * state,ARMword address,ARMword data)37298b9484cSchristos ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
37398b9484cSchristos {
37498b9484cSchristos   ARMword temp, offset;
37598b9484cSchristos 
37698b9484cSchristos   state->NumNcycles++;
37798b9484cSchristos 
37898b9484cSchristos #ifdef VALIDATE
37998b9484cSchristos   if (address == TUBE)
38098b9484cSchristos     {
38198b9484cSchristos       if (data == 4)
38298b9484cSchristos 	state->Emulate = FALSE;
38398b9484cSchristos       else
38498b9484cSchristos 	(void) putc ((char) data, stderr);	/* Write Char */
38598b9484cSchristos       return;
38698b9484cSchristos     }
38798b9484cSchristos #endif
38898b9484cSchristos 
38998b9484cSchristos   temp = ARMul_ReadWord (state, address);
39098b9484cSchristos   offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3;	/* bit offset into the word */
39198b9484cSchristos 
39298b9484cSchristos   PutWord (state, address,
39398b9484cSchristos 	   (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset),
39498b9484cSchristos 	   TRUE);
39598b9484cSchristos }
39698b9484cSchristos 
39798b9484cSchristos /***************************************************************************\
39898b9484cSchristos *                     Write Byte (but don't tell anyone!)                   *
39998b9484cSchristos \***************************************************************************/
40098b9484cSchristos 
40198b9484cSchristos void
ARMul_WriteByte(ARMul_State * state,ARMword address,ARMword data)40298b9484cSchristos ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
40398b9484cSchristos {
40498b9484cSchristos   ARMword temp, offset;
40598b9484cSchristos 
40698b9484cSchristos   temp = ARMul_ReadWord (state, address);
40798b9484cSchristos   offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;	/* bit offset into the word */
40898b9484cSchristos 
40998b9484cSchristos   PutWord (state, address,
41098b9484cSchristos 	   (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
41198b9484cSchristos 	   TRUE);
41298b9484cSchristos }
41398b9484cSchristos 
41498b9484cSchristos /***************************************************************************\
41598b9484cSchristos *                    Store Byte, (Non Sequential Cycle)                     *
41698b9484cSchristos \***************************************************************************/
41798b9484cSchristos 
41898b9484cSchristos void
ARMul_StoreByte(ARMul_State * state,ARMword address,ARMword data)41998b9484cSchristos ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
42098b9484cSchristos {
42198b9484cSchristos   state->NumNcycles++;
42298b9484cSchristos 
42398b9484cSchristos #ifdef VALIDATE
42498b9484cSchristos   if (address == TUBE)
42598b9484cSchristos     {
42698b9484cSchristos       if (data == 4)
42798b9484cSchristos 	state->Emulate = FALSE;
42898b9484cSchristos       else
42998b9484cSchristos 	(void) putc ((char) data, stderr);	/* Write Char */
43098b9484cSchristos       return;
43198b9484cSchristos     }
43298b9484cSchristos #endif
43398b9484cSchristos 
43498b9484cSchristos   ARMul_WriteByte (state, address, data);
43598b9484cSchristos }
43698b9484cSchristos 
43798b9484cSchristos /***************************************************************************\
43898b9484cSchristos *                   Swap Word, (Two Non Sequential Cycles)                  *
43998b9484cSchristos \***************************************************************************/
44098b9484cSchristos 
ARMul_SwapWord(ARMul_State * state,ARMword address,ARMword data)44198b9484cSchristos ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
44298b9484cSchristos {
44398b9484cSchristos   ARMword temp;
44498b9484cSchristos 
44598b9484cSchristos   state->NumNcycles++;
44698b9484cSchristos 
44798b9484cSchristos   temp = ARMul_ReadWord (state, address);
44898b9484cSchristos 
44998b9484cSchristos   state->NumNcycles++;
45098b9484cSchristos 
45198b9484cSchristos   PutWord (state, address, data, TRUE);
45298b9484cSchristos 
45398b9484cSchristos   return temp;
45498b9484cSchristos }
45598b9484cSchristos 
45698b9484cSchristos /***************************************************************************\
45798b9484cSchristos *                   Swap Byte, (Two Non Sequential Cycles)                  *
45898b9484cSchristos \***************************************************************************/
45998b9484cSchristos 
ARMul_SwapByte(ARMul_State * state,ARMword address,ARMword data)46098b9484cSchristos ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
46198b9484cSchristos {
46298b9484cSchristos   ARMword temp;
46398b9484cSchristos 
46498b9484cSchristos   temp = ARMul_LoadByte (state, address);
46598b9484cSchristos   ARMul_StoreByte (state, address, data);
46698b9484cSchristos 
46798b9484cSchristos   return temp;
46898b9484cSchristos }
46998b9484cSchristos 
47098b9484cSchristos /***************************************************************************\
47198b9484cSchristos *                             Count I Cycles                                *
47298b9484cSchristos \***************************************************************************/
47398b9484cSchristos 
47498b9484cSchristos void
ARMul_Icycles(ARMul_State * state,unsigned number,ARMword address ATTRIBUTE_UNUSED)47598b9484cSchristos ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
47698b9484cSchristos {
47798b9484cSchristos   state->NumIcycles += number;
47898b9484cSchristos   ARMul_CLEARABORT;
47998b9484cSchristos }
48098b9484cSchristos 
48198b9484cSchristos /***************************************************************************\
48298b9484cSchristos *                             Count C Cycles                                *
48398b9484cSchristos \***************************************************************************/
48498b9484cSchristos 
48598b9484cSchristos void
ARMul_Ccycles(ARMul_State * state,unsigned number,ARMword address ATTRIBUTE_UNUSED)48698b9484cSchristos ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED)
48798b9484cSchristos {
48898b9484cSchristos   state->NumCcycles += number;
48998b9484cSchristos   ARMul_CLEARABORT;
49098b9484cSchristos }
49198b9484cSchristos 
49298b9484cSchristos 
49398b9484cSchristos /* Read a byte.  Do not check for alignment or access errors.  */
49498b9484cSchristos 
49598b9484cSchristos ARMword
ARMul_SafeReadByte(ARMul_State * state,ARMword address)49698b9484cSchristos ARMul_SafeReadByte (ARMul_State * state, ARMword address)
49798b9484cSchristos {
49898b9484cSchristos   ARMword temp, offset;
49998b9484cSchristos 
50098b9484cSchristos   temp = GetWord (state, address, FALSE);
50198b9484cSchristos   offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
50298b9484cSchristos 
50398b9484cSchristos   return (temp >> offset & 0xffL);
50498b9484cSchristos }
50598b9484cSchristos 
50698b9484cSchristos void
ARMul_SafeWriteByte(ARMul_State * state,ARMword address,ARMword data)50798b9484cSchristos ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data)
50898b9484cSchristos {
50998b9484cSchristos   ARMword temp, offset;
51098b9484cSchristos 
51198b9484cSchristos   temp = GetWord (state, address, FALSE);
51298b9484cSchristos   offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3;
51398b9484cSchristos 
51498b9484cSchristos   PutWord (state, address,
51598b9484cSchristos 	   (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset),
51698b9484cSchristos 	   FALSE);
51798b9484cSchristos }
518