| | 1 | /* Copyright (c) 1992, 2004 by Michael J. Roberts. All Rights Reserved. */ |
| | 2 | /* |
| | 3 | Name |
| | 4 | h_ppc.h - TADS hardware abstraction definitions for PowerPC processor |
| | 5 | Function |
| | 6 | This file provides some machine-dependent routines that allow the TadsVM |
| | 7 | to run on big-endian CPUs (PowerPC on a Mac running OS X, for example). |
| | 8 | |
| | 9 | These definitions are for 32-bit machines only. These probably will |
| | 10 | NOT work on 64-bit hardware. |
| | 11 | Notes |
| | 12 | Created by Nikos Chantziaras. |
| | 13 | |
| | 14 | The arithmetics used in this code are stolen from Iain Merrick's |
| | 15 | HyperTADS interpreter. |
| | 16 | |
| | 17 | The definitions provided here are actually quite generic; they are |
| | 18 | perfectly suitable for little-endian CPUs, like Intel x86 compatibles. |
| | 19 | Anyway, they shouldn't be used for Intel machines, as this generic version |
| | 20 | of the routines is somewhat slower than the ones written specifically for |
| | 21 | x86 CPUs, as Intel compatibles provide hardware support for these routines; |
| | 22 | on Intel compatibles, h_ix86.h should be used instead. |
| | 23 | |
| | 24 | Note that Iain Merrick's original file assigns the copyright to Mike |
| | 25 | Roberts, so that's what I'm going to do here too. |
| | 26 | Modified |
| | 27 | 05/19/04 MJRoberts - added to main TADS source tree |
| | 28 | 05/17/04 Nikos Chantziaras - created |
| | 29 | */ |
| | 30 | |
| | 31 | #ifndef H_PPC_H |
| | 32 | #define H_PPC_H |
| | 33 | |
| | 34 | /* |
| | 35 | * Round a size up to worst-case alignment boundary. |
| | 36 | */ |
| | 37 | #define osrndsz(s) (((s) + 3) & ~3) |
| | 38 | |
| | 39 | /* |
| | 40 | * Round a pointer up to worst-case alignment boundary. |
| | 41 | */ |
| | 42 | #define osrndpt(p) ((unsigned char*)((((unsigned long)(p)) + 3) & ~3)) |
| | 43 | |
| | 44 | /* |
| | 45 | * Service macros for osrp2 etc. |
| | 46 | */ |
| | 47 | #define osc2u(p,i) ((unsigned short)(((unsigned char*)(p))[i])) |
| | 48 | #define osc2l(p,i) ((unsigned long)(((unsigned char*)(p))[i])) |
| | 49 | #define osc2s(p,i) ((short)(((signed char*)(p))[i])) |
| | 50 | #define osc2sl(p,i) ((long)(((signed char*)(p))[i])) |
| | 51 | |
| | 52 | /* |
| | 53 | * Read an unaligned portable unsigned 2-byte value, returning an int |
| | 54 | * value. |
| | 55 | */ |
| | 56 | #define osrp2(p) (osc2u(p,0) + (osc2u(p,1) << 8)) |
| | 57 | |
| | 58 | /* |
| | 59 | * Read an unaligned portable signed 2-byte value, returning int. |
| | 60 | */ |
| | 61 | #define osrp2s(p) (((short)osc2u(p,0)) + (osc2s(p,1) << 8)) |
| | 62 | |
| | 63 | /* |
| | 64 | * Write int to unaligned portable 2-byte value. |
| | 65 | */ |
| | 66 | #define oswp2(p,i) \ |
| | 67 | ((((unsigned char*)(p))[1] = (i) >> 8), \ |
| | 68 | (((unsigned char*)(p))[0] = (i) & 255)) |
| | 69 | |
| | 70 | /* |
| | 71 | * Read an unaligned portable 4-byte value, returning long. |
| | 72 | */ |
| | 73 | #define osrp4(p) \ |
| | 74 | (((long)osc2l(p,0)) \ |
| | 75 | + ((long)(osc2l(p,1)) << 8) \ |
| | 76 | + ((long)(osc2l(p,2) << 16)) \ |
| | 77 | + (osc2sl(p,3) << 24)) |
| | 78 | |
| | 79 | /* |
| | 80 | * Write a long to an unaligned portable 4-byte value. |
| | 81 | */ |
| | 82 | #define oswp4(p,i) \ |
| | 83 | ((((unsigned char*)(p))[0] = (i)), \ |
| | 84 | (((unsigned char*)(p))[1] = (i) >> 8), \ |
| | 85 | (((unsigned char*)(p))[2] = (i) >> 16, \ |
| | 86 | (((unsigned char*)(p))[3] = (i) >> 24))) |
| | 87 | |
| | 88 | #endif /* H_PPC_H */ |