From eb3074a4fe3b7c86d2a3ca139eb881964f2f23e1 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 18 Dec 2009 15:43:29 +0000 Subject: Update to use stdint/stdbool.h git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2383 42af7a65-404d-4744-a932-0658087f49c3 --- misc/pascal/insn16/include/pexec.h | 312 +- misc/pascal/insn16/libinsn/pdasm.c | 1131 ++++---- misc/pascal/insn16/libinsn/pgen.c | 623 ++-- misc/pascal/insn16/libinsn/pgetopcode.c | 278 +- misc/pascal/insn16/libinsn/preloc.c | 296 +- misc/pascal/insn16/plist/plist.c | 719 ++--- misc/pascal/insn16/popt/pcopt.c | 1811 ++++++------ misc/pascal/insn16/popt/pcopt.h | 100 +- misc/pascal/insn16/popt/pfopt.c | 383 +-- misc/pascal/insn16/popt/pjopt.c | 899 +++--- misc/pascal/insn16/popt/pjopt.h | 92 +- misc/pascal/insn16/popt/plopt.c | 499 ++-- misc/pascal/insn16/popt/plopt.h | 98 +- misc/pascal/insn16/popt/polocal.c | 601 ++-- misc/pascal/insn16/popt/polocal.h | 147 +- misc/pascal/insn16/popt/popt.c | 577 ++-- misc/pascal/insn16/popt/psopt.c | 281 +- misc/pascal/insn16/prun/pdbg.c | 1494 +++++----- misc/pascal/insn16/prun/pexec.c | 4748 ++++++++++++++++--------------- misc/pascal/insn16/prun/pload.c | 351 +-- misc/pascal/insn16/prun/prun.c | 556 ++-- 21 files changed, 8025 insertions(+), 7971 deletions(-) (limited to 'misc/pascal/insn16') diff --git a/misc/pascal/insn16/include/pexec.h b/misc/pascal/insn16/include/pexec.h index 234ffb99e..e3717ca73 100644 --- a/misc/pascal/insn16/include/pexec.h +++ b/misc/pascal/insn16/include/pexec.h @@ -1,156 +1,156 @@ -/**************************************************************************** - * pexec.h - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#ifndef __PEXEC_H -#define __PEXEC_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -#define BPERI 2 -#define ITOBSTACK(i) ((i) << 1) -#define BTOISTACK(i) ((i) >> 1) -#define ROUNDBTOI(i) (((i) + 1) >> 1) - -/**************************************************************************** - * Type Definitions - ****************************************************************************/ - -typedef uint16 ustack_t; /* Stack values are 16-bits in length */ -typedef sint16 sstack_t; -typedef uint16 addr_t; /* Addresses are 16-bits in length */ -typedef uint16 level_t; /* Limits to MAXUINT16 levels */ - -union stack_u -{ - ustack_t *i; - ubyte *b; -}; -typedef union stack_u stackType; - -/* This structure describes the parameters needed to initialize the p-code - * interpreter. - */ - -struct pexec_attr_s -{ - /* Instruction space (I-Space) */ - - FAR ubyte *ispace; /* Allocated I-Space containing p-code data */ - addr_t entry; /* Entry point */ - addr_t maxpc; /* Last valid p-code address */ - - /* Read-only data block */ - - FAR ubyte *rodata; /* Address of read-only data block */ - addr_t rosize; /* Size of read-only data block */ - - /* Allocate for variable storage */ - - addr_t varsize; /* Variable storage size */ - addr_t strsize; /* String storage size */ -}; - -/* This structure defines the current state of the p-code interpreter */ - -struct pexec_s -{ - /* This is the emulated P-Machine stack (D-Space) */ - - stackType dstack; - - /* This is the emulated P-Machine instruction space (I-Space) */ - - FAR ubyte *ispace; - - /* Address of last valid P-Code */ - - addr_t maxpc; - - /* These are the emulated P-Machine registers: - * - * spb: Base of the stack - * sp: The Pascal stack pointer - * csp: The current top of the stack used to manage string - * storage - * fp: Base Register of the current stack frame. Holds the address - * of the base of the stack frame of the current block. - * fop: Pointer to section containing read-only data - * pc: Holds the current p-code location - */ - - addr_t spb; /* Pascal stack base */ - addr_t sp; /* Pascal stack pointer */ - addr_t csp; /* Character stack pointer */ - addr_t fp; /* Base of the current frame */ - addr_t rop; /* Read-only data pointer */ - addr_t pc; /* Program counter */ - - /* Info needed to perform a simulated reset */ - - addr_t strsize; /* String stack size */ - addr_t rosize; /* Read-only stack size */ - addr_t entry; /* Entry point */ - addr_t stacksize; /* (debug only) */ -}; - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" { -#else -#define EXTERN extern -#endif - -EXTERN FAR struct pexec_s *pload(const char *filename, addr_t varsize, addr_t strsize); -EXTERN FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr); -EXTERN int pexec(FAR struct pexec_s *st); -EXTERN void pexec_reset(struct pexec_s *st); -EXTERN void pexec_release(struct pexec_s *st); - -#undef EXTERN -#ifdef __cplusplus -} -#endif - -#endif /* __PEXEC_H */ +/**************************************************************************** + * pexec.h + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __PEXEC_H +#define __PEXEC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define BPERI 2 +#define ITOBSTACK(i) ((i) << 1) +#define BTOISTACK(i) ((i) >> 1) +#define ROUNDBTOI(i) (((i) + 1) >> 1) + +/**************************************************************************** + * Type Definitions + ****************************************************************************/ + +typedef uint16_t ustack_t; /* Stack values are 16-bits in length */ +typedef int16_t sstack_t; +typedef uint16_t addr_t; /* Addresses are 16-bits in length */ +typedef uint16_t level_t; /* Limits to MAXUINT16 levels */ + +union stack_u +{ + ustack_t *i; + uint8_t *b; +}; +typedef union stack_u stackType; + +/* This structure describes the parameters needed to initialize the p-code + * interpreter. + */ + +struct pexec_attr_s +{ + /* Instruction space (I-Space) */ + + FAR uint8_t *ispace; /* Allocated I-Space containing p-code data */ + addr_t entry; /* Entry point */ + addr_t maxpc; /* Last valid p-code address */ + + /* Read-only data block */ + + FAR uint8_t *rodata; /* Address of read-only data block */ + addr_t rosize; /* Size of read-only data block */ + + /* Allocate for variable storage */ + + addr_t varsize; /* Variable storage size */ + addr_t strsize; /* String storage size */ +}; + +/* This structure defines the current state of the p-code interpreter */ + +struct pexec_s +{ + /* This is the emulated P-Machine stack (D-Space) */ + + stackType dstack; + + /* This is the emulated P-Machine instruction space (I-Space) */ + + FAR uint8_t *ispace; + + /* Address of last valid P-Code */ + + addr_t maxpc; + + /* These are the emulated P-Machine registers: + * + * spb: Base of the stack + * sp: The Pascal stack pointer + * csp: The current top of the stack used to manage string + * storage + * fp: Base Register of the current stack frame. Holds the address + * of the base of the stack frame of the current block. + * fop: Pointer to section containing read-only data + * pc: Holds the current p-code location + */ + + addr_t spb; /* Pascal stack base */ + addr_t sp; /* Pascal stack pointer */ + addr_t csp; /* Character stack pointer */ + addr_t fp; /* Base of the current frame */ + addr_t rop; /* Read-only data pointer */ + addr_t pc; /* Program counter */ + + /* Info needed to perform a simulated reset */ + + addr_t strsize; /* String stack size */ + addr_t rosize; /* Read-only stack size */ + addr_t entry; /* Entry point */ + addr_t stacksize; /* (debug only) */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +EXTERN FAR struct pexec_s *pload(const char *filename, addr_t varsize, addr_t strsize); +EXTERN FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr); +EXTERN int pexec(FAR struct pexec_s *st); +EXTERN void pexec_reset(struct pexec_s *st); +EXTERN void pexec_release(struct pexec_s *st); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __PEXEC_H */ diff --git a/misc/pascal/insn16/libinsn/pdasm.c b/misc/pascal/insn16/libinsn/pdasm.c index 9ee8f4b63..b6c1ecb31 100644 --- a/misc/pascal/insn16/libinsn/pdasm.c +++ b/misc/pascal/insn16/libinsn/pdasm.c @@ -1,562 +1,569 @@ -/********************************************************************** - * pdasm.c - * P-Code Disassembler - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -#include - -#include "keywords.h" -#include "podefs.h" -#include "pinsn16.h" -#include "pfdefs.h" -#include "pxdefs.h" -#include "paslib.h" - -#include "pinsn.h" - -/***********************************************************************/ - -/* These are all the format codes that apply to opcodes the an arg16 */ - -#define NOARG16 0 -#define HEX 1 -#define DECIMAL 2 -#define UDECIMAL 3 -#define LABEL_DEC 4 -#define xOP 5 -#define lbOP 6 -#define fpOP 7 -#define COMMENT 8 - -/* The following table defines everything that is needed to disassemble - * a P-Code. NOTE: The order of definition in this table must exactly - * match the declaration sequence in pinsn.h. */ - -static const char invOp[] = "Invalid Opcode"; -static const struct -{ - const char *opName; /* Opcode mnemonics */ - ubyte format; /* arg16 format */ -} opTable[256] = -{ - -/******************* OPCODES WITH NO ARGUMENTS ************************/ -/* Program control (No stack arguments) */ - -/* 0x00 */ { "NOP ", NOARG16 }, - -/* Arithmetic & logical & and integer conversions (One stack argument) */ - -/* 0x01 */ { "NEG ", NOARG16 }, -/* 0x02 */ { "ABS ", NOARG16 }, -/* 0x03 */ { "INC ", NOARG16 }, -/* 0x04 */ { "DEC ", NOARG16 }, -/* 0x05 */ { "NOT ", NOARG16 }, - -/* Arithmetic & logical (Two stack arguments) */ - -/* 0x06 */ { "ADD ", NOARG16 }, -/* 0x07 */ { "SUB ", NOARG16 }, -/* 0x08 */ { "MUL ", NOARG16 }, -/* 0x09 */ { "DIV ", NOARG16 }, -/* 0x0a */ { "MOD ", NOARG16 }, -/* 0x0b */ { "SLL ", NOARG16 }, -/* 0x0c */ { "SRL ", NOARG16 }, -/* 0x0d */ { "SRA ", NOARG16 }, -/* 0x0e */ { "OR ", NOARG16 }, -/* 0x0f */ { "AND ", NOARG16 }, - -/* Comparisons (One stack argument) */ - -/* 0x10 */ { "EQUZ ", NOARG16 }, -/* 0x11 */ { "NEQZ ", NOARG16 }, -/* 0x12 */ { "LTZ ", NOARG16 }, -/* 0x13 */ { "GTEZ ", NOARG16 }, -/* 0x14 */ { "GTZ ", NOARG16 }, -/* 0x15 */ { "LTEZ ", NOARG16 }, -/* 0x16 */ { invOp, NOARG16 }, -/* 0x17 */ { invOp, NOARG16 }, - -/* Comparisons (Two stack arguments) */ - -/* 0x18 */ { "EQU ", NOARG16 }, -/* 0x19 */ { "NEQ ", NOARG16 }, -/* 0x1a */ { "LT ", NOARG16 }, -/* 0x1b */ { "GTE ", NOARG16 }, -/* 0x1c */ { "GT ", NOARG16 }, -/* 0x1d */ { "LTE ", NOARG16 }, -/* 0x1e */ { invOp, NOARG16 }, -/* 0x1f */ { "BIT ", NOARG16 }, - -/* Load (One) or Store (Two stack argument) */ - -/* 0x20 */ { "LDI ", NOARG16 }, -/* 0x21 */ { "LDIH", NOARG16 }, -/* 0x22 */ { "LDIB", NOARG16 }, -/* 0x23 */ { "LDIM", NOARG16 }, -/* 0x24 */ { "STI ", NOARG16 }, -/* 0x25 */ { "STIH", NOARG16 }, -/* 0x26 */ { "STIB", NOARG16 }, -/* 0x27 */ { "STIM", NOARG16 }, - -/* Data stack operations */ - -/* 0x29 */ { "DUP ", NOARG16 }, -/* 0x29 */ { "DUPH ", NOARG16 }, -/* 0x2a */ { "PUSHS", NOARG16 }, -/* 0x2b */ { "POPS", NOARG16 }, -/* 0x2c */ { invOp, NOARG16 }, -/* 0x2d */ { invOp, NOARG16 }, -/* 0x2e */ { invOp, NOARG16 }, -/* 0x2f */ { "RET ", NOARG16 }, - -/* 0x30 */ { invOp, NOARG16 }, -/* 0x31 */ { invOp, NOARG16 }, -/* 0x32 */ { invOp, NOARG16 }, -/* 0x33 */ { invOp, NOARG16 }, -/* 0x34 */ { invOp, NOARG16 }, -/* 0x35 */ { invOp, NOARG16 }, -/* 0x36 */ { invOp, NOARG16 }, -/* 0x37 */ { invOp, NOARG16 }, -/* 0x38 */ { invOp, NOARG16 }, - -/* System Functions (No stack arguments) */ - -/* 0x39 */ { invOp, NOARG16 }, -/* 0x3a */ { invOp, NOARG16 }, -/* 0x3b */ { invOp, NOARG16 }, -/* 0x3c */ { invOp, NOARG16 }, -/* 0x3d */ { invOp, NOARG16 }, -/* 0x3e */ { invOp, NOARG16 }, -/* 0x3f */ { "EXIT ", NOARG16 }, - -/************** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ***************/ - -/* 0x40 */ { invOp, NOARG16 }, -/* 0x41 */ { invOp, NOARG16 }, -/* 0x42 */ { invOp, NOARG16 }, -/* 0x43 */ { invOp, NOARG16 }, -/* 0x44 */ { invOp, NOARG16 }, -/* 0x45 */ { invOp, NOARG16 }, -/* 0x46 */ { invOp, NOARG16 }, -/* 0x47 */ { invOp, NOARG16 }, -/* 0x48 */ { invOp, NOARG16 }, -/* 0x49 */ { invOp, NOARG16 }, -/* 0x4a */ { invOp, NOARG16 }, -/* 0x4b */ { invOp, NOARG16 }, -/* 0x4c */ { invOp, NOARG16 }, -/* 0x4d */ { invOp, NOARG16 }, -/* 0x4e */ { invOp, NOARG16 }, -/* 0x4f */ { invOp, NOARG16 }, - -/* 0x50 */ { invOp, NOARG16 }, -/* 0x51 */ { invOp, NOARG16 }, -/* 0x52 */ { invOp, NOARG16 }, -/* 0x53 */ { invOp, NOARG16 }, -/* 0x54 */ { invOp, NOARG16 }, -/* 0x55 */ { invOp, NOARG16 }, -/* 0x56 */ { invOp, NOARG16 }, -/* 0x57 */ { invOp, NOARG16 }, -/* 0x58 */ { invOp, NOARG16 }, -/* 0x59 */ { invOp, NOARG16 }, -/* 0x5a */ { invOp, NOARG16 }, -/* 0x5b */ { invOp, NOARG16 }, -/* 0x5c */ { invOp, NOARG16 }, -/* 0x5d */ { invOp, NOARG16 }, -/* 0x5e */ { invOp, NOARG16 }, -/* 0x5f */ { invOp, NOARG16 }, - -/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */ - -/* 0x60 */ { invOp, NOARG16 }, -/* 0x61 */ { invOp, NOARG16 }, -/* 0x62 */ { invOp, NOARG16 }, -/* 0x63 */ { invOp, NOARG16 }, -/* 0x64 */ { invOp, NOARG16 }, -/* 0x65 */ { invOp, NOARG16 }, -/* 0x66 */ { invOp, NOARG16 }, -/* 0x67 */ { invOp, NOARG16 }, -/* 0x68 */ { invOp, NOARG16 }, -/* 0x69 */ { invOp, NOARG16 }, -/* 0x6a */ { invOp, NOARG16 }, -/* 0x6b */ { invOp, NOARG16 }, -/* 0x6c */ { invOp, NOARG16 }, -/* 0x6d */ { invOp, NOARG16 }, -/* 0x6e */ { invOp, NOARG16 }, -/* 0x6f */ { invOp, NOARG16 }, - -/* Floating Point Operations: arg8 = FP op-code */ - -/* 0x70 */ { "FLOAT", fpOP }, -/* 0x71 */ { invOp, NOARG16 }, -/* 0x72 */ { invOp, NOARG16 }, -/* 0x73 */ { invOp, NOARG16 }, -/* 0x74 */ { "PUSHB", NOARG16 }, -/* 0x75 */ { invOp, NOARG16 }, -/* 0x76 */ { invOp, NOARG16 }, -/* 0x77 */ { invOp, NOARG16 }, - -/* 0x78 */ { invOp, NOARG16 }, -/* 0x79 */ { invOp, NOARG16 }, -/* 0x7a */ { invOp, NOARG16 }, -/* 0x7b */ { invOp, NOARG16 }, -/* 0x7c */ { invOp, NOARG16 }, -/* 0x7d */ { invOp, NOARG16 }, -/* 0x7e */ { invOp, NOARG16 }, -/* 0x7f */ { invOp, NOARG16 }, - -/************ OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) ************/ - -/* 0x80 */ { invOp, NOARG16 }, -/* 0x81 */ { invOp, NOARG16 }, -/* 0x82 */ { invOp, NOARG16 }, -/* 0x83 */ { invOp, NOARG16 }, -/* 0x84 */ { invOp, NOARG16 }, -/* 0x85 */ { invOp, NOARG16 }, -/* 0x86 */ { invOp, NOARG16 }, -/* 0x87 */ { invOp, NOARG16 }, -/* 0x88 */ { invOp, NOARG16 }, -/* 0x89 */ { invOp, NOARG16 }, -/* 0x8a */ { invOp, NOARG16 }, -/* 0x8b */ { invOp, NOARG16 }, -/* 0x8c */ { invOp, NOARG16 }, -/* 0x8d */ { invOp, NOARG16 }, -/* 0x8e */ { invOp, NOARG16 }, -/* 0x8f */ { invOp, NOARG16 }, - -/* Program control: arg16 = unsigned label (One stack argument) */ - -/* 0x90 */ { "JEQUZ", HEX }, -/* 0x91 */ { "JNEQZ", HEX }, -/* 0x92 */ { "JLTZ ", HEX }, -/* 0x93 */ { "JGTEZ", HEX }, -/* 0x94 */ { "JGTZ ", HEX }, -/* 0x95 */ { "JLTEZ", HEX }, - -/* Program control: arg16 = unsigned label (no stack arguments) */ - -/* 0x96 */ { "JMP ", HEX }, -/* 0x97 */ { invOp, NOARG16 }, - -/* Program control: arg16 = unsigned label (One stack argument) */ - -/* 0x98 */ { "JEQU ", HEX }, -/* 0x99 */ { "JNEQ ", HEX }, -/* 0x9a */ { "JLT ", HEX }, -/* 0x9b */ { "JGTE ", HEX }, -/* 0x9c */ { "JGT ", HEX }, -/* 0x9d */ { "JLTE ", HEX }, -/* 0x9e */ { invOp, NOARG16 }, -/* 0x9f */ { invOp, NOARG16 }, - -/* Data stack: arg16 = 16 bit signed data (no stack arguments) */ - -/* Load: arg16 = unsigned base offset (no stack arguments) */ - -/* 0xa0 */ { "LD ", UDECIMAL }, -/* 0xa1 */ { "LDH ", UDECIMAL }, -/* 0xa2 */ { "LDB ", UDECIMAL }, -/* 0xa3 */ { "LDM ", UDECIMAL }, - -/* Store: arg16 = unsigned base offset (One stack arguments) */ - -/* 0xa4 */ { "ST ", UDECIMAL }, -/* 0xa5 */ { "STH ", UDECIMAL }, -/* 0xa6 */ { "STB ", UDECIMAL }, -/* 0xa7 */ { "STM ", UDECIMAL }, - -/* Load Indexed: arg16 = unsigned base offset (One stack arguments) */ - -/* 0xa8 */ { "LDX ", UDECIMAL }, -/* 0xa9 */ { "LDXH ", UDECIMAL }, -/* 0xaa */ { "LDXB ", UDECIMAL }, -/* 0xab */ { "LDXM ", UDECIMAL }, - -/* Store Indexed: arg16 = unsigned base offset (Two stack arguments) */ - -/* 0xac */ { "STX ", UDECIMAL }, -/* 0xad */ { "STXH ", UDECIMAL }, -/* 0xae */ { "STXB ", UDECIMAL }, -/* 0xaf */ { "STXM ", UDECIMAL }, - -/* 0xb0 */ { "LA ", UDECIMAL }, -/* 0xb1 */ { "LAC ", HEX, }, -/* 0xb2 */ { invOp, NOARG16 }, -/* 0xb3 */ { invOp, NOARG16 }, -/* 0xb4 */ { "PUSH ", DECIMAL }, -/* 0xb5 */ { "INDS ", DECIMAL }, -/* 0xb6 */ { invOp, NOARG16 }, -/* 0xb7 */ { invOp, NOARG16 }, -/* 0xb8 */ { "LAX ", UDECIMAL }, - -/* System operations: arg16 = 16-bit library function identifer */ - -/* 0xb9 */ { "LIB ", lbOP, }, -/* 0xba */ { invOp, NOARG16 }, -/* 0xbb */ { invOp, NOARG16 }, -/* 0xbc */ { invOp, NOARG16 }, -/* 0xbd */ { invOp, NOARG16 }, -/* 0xbe */ { invOp, NOARG16 }, - -/* Program control: arg16 = unsigned label (no stack arguments) */ - -/* 0xbf */ { "LABEL", LABEL_DEC }, - -/**** OPCODES WITH BYTE ARGUMENT (arg8) AND 16-BIT ARGUMENT (arg16) ****/ - -/* 0xc0 */ { invOp, NOARG16 }, -/* 0xc1 */ { invOp, NOARG16 }, -/* 0xc2 */ { invOp, NOARG16 }, -/* 0xc3 */ { invOp, NOARG16 }, -/* 0xc4 */ { invOp, NOARG16 }, -/* 0xc5 */ { invOp, NOARG16 }, -/* 0xc6 */ { invOp, NOARG16 }, -/* 0xc7 */ { invOp, NOARG16 }, - -/* Program Control: arg8 = level; arg16 = unsigned label (No stack - * arguments */ - -/* 0xc8 */ { "PCAL ", HEX }, -/* 0xc9 */ { invOp, NOARG16 }, -/* 0xca */ { invOp, NOARG16 }, -/* 0xcb */ { invOp, NOARG16 }, -/* 0xcc */ { invOp, NOARG16 }, -/* 0xcd */ { invOp, NOARG16 }, -/* 0xce */ { invOp, NOARG16 }, -/* 0xcf */ { invOp, NOARG16 }, - -/* 0xd0 */ { invOp, NOARG16 }, -/* 0xd1 */ { invOp, NOARG16 }, -/* 0xd2 */ { invOp, NOARG16 }, -/* 0xd3 */ { invOp, NOARG16 }, -/* 0xd4 */ { invOp, NOARG16 }, -/* 0xd5 */ { invOp, NOARG16 }, -/* 0xd6 */ { invOp, NOARG16 }, -/* 0xd7 */ { invOp, NOARG16 }, -/* 0xd8 */ { invOp, NOARG16 }, -/* 0xd9 */ { invOp, NOARG16 }, -/* 0xda */ { invOp, NOARG16 }, -/* 0xdb */ { invOp, NOARG16 }, -/* 0xdc */ { invOp, NOARG16 }, -/* 0xdd */ { invOp, NOARG16 }, -/* 0xde */ { invOp, NOARG16 }, -/* 0xdf */ { invOp, NOARG16 }, - -/* Load: arg8 = level; arg16 = signed frame offset (no stack arguments) */ - -/* 0xe0 */ { "LDS ", DECIMAL }, -/* 0xe1 */ { "LDSH ", DECIMAL }, -/* 0xe2 */ { "LDSB ", DECIMAL }, -/* 0xe3 */ { "LDSM ", DECIMAL }, - -/* Store: arg8 = level; arg16 = signed frame offset (One stack arguments) */ - -/* 0xe4 */ { "STS ", DECIMAL }, -/* 0xe5 */ { "STSH ", DECIMAL }, -/* 0xe6 */ { "STSB ", DECIMAL }, -/* 0xe7 */ { "STSM ", DECIMAL }, - -/* Load Indexed: arg8 = level; arg16 = signed frame offset (One stack arguments) */ - -/* 0xe8 */ { "LDSX ", DECIMAL }, -/* 0xe9 */ { "LDSXH", DECIMAL }, -/* 0xea */ { "LDSXB", DECIMAL }, -/* 0xeb */ { "LDSXM", DECIMAL }, - -/* Store Indexed: arg8 = level; arg16 = signed frame offset (Two stack arguments) */ - -/* 0xec */ { "STSX ", DECIMAL }, -/* 0xed */ { "STSXH", DECIMAL }, -/* 0xee */ { "STSXB", DECIMAL }, -/* 0xef */ { "STSXM", DECIMAL }, - -/* Load Address: arg8 = level; arg16 = signed frame offset (no stack arguments) */ - -/* 0xf0 */ { "LAS ", DECIMAL }, -/* 0xf1 */ { invOp, NOARG16 }, -/* 0xf2 */ { invOp, NOARG16 }, -/* 0xf3 */ { invOp, NOARG16 }, -/* 0xf4 */ { invOp, NOARG16 }, -/* 0xf5 */ { invOp, NOARG16 }, -/* 0xf6 */ { invOp, NOARG16 }, -/* 0xf7 */ { invOp, NOARG16 }, -/* 0xf8 */ { "LASX ", DECIMAL }, - -/* System Functions: (No stack arguments) - * For SYSIO: arg8 = file number; arg16 = sub-function code - */ - -/* 0xf9 */ { "SYSIO", xOP, }, -/* 0xfa */ { invOp, NOARG16 }, -/* 0xfb */ { invOp, NOARG16 }, -/* 0xfc */ { invOp, NOARG16 }, -/* 0xfd */ { invOp, NOARG16 }, -/* 0xfe */ { invOp, NOARG16 }, - -/* Psuedo-operations: - * For LINE: arg8 = file number; arg16 = line number - */ - -/* 0xff */ { "LINE ", COMMENT }, -}; - -static const char invXOp[] = "Invalid SYSIO"; -static const char *xName[MAX_XOP] = { /* SYSIO opcode mnemonics */ -/* 0x00 */ invXOp, "EOF", "EOLN", "RESET", -/* 0x04 */ "REWRITE", invXOp, invXOp, invXOp, -/* 0x08 */ invXOp, invXOp, invXOp, invXOp, -/* 0x0c */ invXOp, invXOp, invXOp, invXOp, -/* 0x10 */ "READLN", "READPG", "READBIN", "READINT", -/* 0x14 */ "READCHR", "READSTR", "READRL", invXOp, -/* 0x18 */ invXOp, invXOp, invXOp, invXOp, -/* 0x1c */ invXOp, invXOp, invXOp, invXOp, -/* 0x20 */ "WRITELN", "WRITEPG", "WRITEBIN", "WRITEINT", -/* 0x24 */ "WRITECHR", "WRITESTR", "WRITERL" }; - -static const char invLbOp[] = "Invalid runtime code"; -static const char *lbName[MAX_LBOP] = { /* LIB opcode mnemonics */ -/* 0x00 */ "GETENV", "STR2STR", "CSTR2STR", "STR2RSTR", -/* 0x04 */ "CSTR2RSTR", "VAL", "MKSTK", "MKSTKSTR", -/* 0x08 */ "MKSTKC", "STRCAT", "STRCATC", "STRCMP" }; - -static const char invFpOp[] = "Invalid FP Operation"; -static const char *fpName[MAX_FOP] = { -/* 0x00 */ invFpOp, "FLOAT", "TRUNC", "ROUND", -/* 0x04 */ "ADD", "SUB", "MUL", "DIV", -/* 0x08 */ "MOD", invFpOp, "EQU", "NEQ", -/* 0x0c */ "LT", "GTE", "GT", "LTE", -/* 0x10 */ "NEG", "ABS", "SQR", "SQRT", -/* 0x14 */ "SIN", "COS", "ATAN", "LN", -/* 0x18 */ "EXP" }; - -/***********************************************************************/ - -void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop) -{ - /* Indent, comment or label */ - - switch (opTable[pop->op].format) - { - case LABEL_DEC : - fprintf(lfile, "L%04x: ", pop->arg2); - break; - case COMMENT : - fprintf(lfile, "; "); - break; - default : - fprintf(lfile, " "); - } /* end switch */ - - /* Special Case Comment line format */ - - if (opTable[pop->op].format == COMMENT) - { - fprintf(lfile, "%s ", opTable[pop->op].opName); - if (pop->op & o8) - { - fprintf(lfile, "%d", pop->arg1); - if (pop->op & o16) - fprintf(lfile, ":%d", pop->arg2); - } /* end if */ - else if (pop->op & o16) - fprintf(lfile, "%d", pop->arg2); - } /* end if */ - - /* Print normal opCode mnemonic */ - - else - { - fprintf(lfile, "%s ", opTable[pop->op].opName); - - /* Print pop->arg1 (if present) */ - - if (pop->op & o8) fprintf(lfile, "%d", pop->arg1); - - /* Print ar16 (if present) */ - - if (pop->op & o16) - { - switch (opTable[pop->op].format) - { - case HEX : - if (pop->op & o8) fprintf(lfile, ", "); - fprintf(lfile, "0x%04x", pop->arg2); - break; - - case COMMENT : - case DECIMAL : - if (pop->op & o8) fprintf(lfile, ", "); - fprintf(lfile, "%ld", signExtend16(pop->arg2)); - break; - - case UDECIMAL : - if (pop->op & o8) fprintf(lfile, ", "); - fprintf(lfile, "%u", pop->arg2); - break; - - case fpOP : - if ((pop->arg1 & fpMASK) < MAX_FOP) - fprintf(lfile, " %s", fpName[(pop->arg1 & 0x3f)]); - else - fprintf(lfile, " %s", invFpOp); - break; - - case xOP : - if (pop->arg2 < MAX_XOP) - fprintf(lfile, ", %s", xName[pop->arg2]); - else - fprintf(lfile, ", %s", invXOp); - break; - - case lbOP : - if (pop->arg2 < MAX_LBOP) - fprintf(lfile, "%s", lbName[pop->arg2]); - else - fprintf(lfile, "%s", invLbOp); - break; - - case LABEL_DEC : - default : - break; - } /* end switch */ - } /* end if */ - } /* end else */ - - /* Don't forget the newline! */ - - fputc('\n', lfile); - -} /* end dissassemblePcode */ - -/***********************************************************************/ +/********************************************************************** + * pdasm.c + * P-Code Disassembler + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/*********************************************************************** + * Included Files + ***********************************************************************/ + +#include +#include + +#include "keywords.h" +#include "podefs.h" +#include "pinsn16.h" +#include "pfdefs.h" +#include "pxdefs.h" +#include "paslib.h" + +#include "pinsn.h" + +/*********************************************************************** + * Pre-processor Definitions + ***********************************************************************/ + +/* These are all the format codes that apply to opcodes the an arg16 */ + +#define NOARG16 0 +#define HEX 1 +#define DECIMAL 2 +#define UDECIMAL 3 +#define LABEL_DEC 4 +#define xOP 5 +#define lbOP 6 +#define fpOP 7 +#define COMMENT 8 + +/* The following table defines everything that is needed to disassemble + * a P-Code. NOTE: The order of definition in this table must exactly + * match the declaration sequence in pinsn.h. */ + +static const char invOp[] = "Invalid Opcode"; +static const struct +{ + const char *opName; /* Opcode mnemonics */ + uint8_t format; /* arg16 format */ +} opTable[256] = +{ + +/******************* OPCODES WITH NO ARGUMENTS ************************/ +/* Program control (No stack arguments) */ + +/* 0x00 */ { "NOP ", NOARG16 }, + +/* Arithmetic & logical & and integer conversions (One stack argument) */ + +/* 0x01 */ { "NEG ", NOARG16 }, +/* 0x02 */ { "ABS ", NOARG16 }, +/* 0x03 */ { "INC ", NOARG16 }, +/* 0x04 */ { "DEC ", NOARG16 }, +/* 0x05 */ { "NOT ", NOARG16 }, + +/* Arithmetic & logical (Two stack arguments) */ + +/* 0x06 */ { "ADD ", NOARG16 }, +/* 0x07 */ { "SUB ", NOARG16 }, +/* 0x08 */ { "MUL ", NOARG16 }, +/* 0x09 */ { "DIV ", NOARG16 }, +/* 0x0a */ { "MOD ", NOARG16 }, +/* 0x0b */ { "SLL ", NOARG16 }, +/* 0x0c */ { "SRL ", NOARG16 }, +/* 0x0d */ { "SRA ", NOARG16 }, +/* 0x0e */ { "OR ", NOARG16 }, +/* 0x0f */ { "AND ", NOARG16 }, + +/* Comparisons (One stack argument) */ + +/* 0x10 */ { "EQUZ ", NOARG16 }, +/* 0x11 */ { "NEQZ ", NOARG16 }, +/* 0x12 */ { "LTZ ", NOARG16 }, +/* 0x13 */ { "GTEZ ", NOARG16 }, +/* 0x14 */ { "GTZ ", NOARG16 }, +/* 0x15 */ { "LTEZ ", NOARG16 }, +/* 0x16 */ { invOp, NOARG16 }, +/* 0x17 */ { invOp, NOARG16 }, + +/* Comparisons (Two stack arguments) */ + +/* 0x18 */ { "EQU ", NOARG16 }, +/* 0x19 */ { "NEQ ", NOARG16 }, +/* 0x1a */ { "LT ", NOARG16 }, +/* 0x1b */ { "GTE ", NOARG16 }, +/* 0x1c */ { "GT ", NOARG16 }, +/* 0x1d */ { "LTE ", NOARG16 }, +/* 0x1e */ { invOp, NOARG16 }, +/* 0x1f */ { "BIT ", NOARG16 }, + +/* Load (One) or Store (Two stack argument) */ + +/* 0x20 */ { "LDI ", NOARG16 }, +/* 0x21 */ { "LDIH", NOARG16 }, +/* 0x22 */ { "LDIB", NOARG16 }, +/* 0x23 */ { "LDIM", NOARG16 }, +/* 0x24 */ { "STI ", NOARG16 }, +/* 0x25 */ { "STIH", NOARG16 }, +/* 0x26 */ { "STIB", NOARG16 }, +/* 0x27 */ { "STIM", NOARG16 }, + +/* Data stack operations */ + +/* 0x29 */ { "DUP ", NOARG16 }, +/* 0x29 */ { "DUPH ", NOARG16 }, +/* 0x2a */ { "PUSHS", NOARG16 }, +/* 0x2b */ { "POPS", NOARG16 }, +/* 0x2c */ { invOp, NOARG16 }, +/* 0x2d */ { invOp, NOARG16 }, +/* 0x2e */ { invOp, NOARG16 }, +/* 0x2f */ { "RET ", NOARG16 }, + +/* 0x30 */ { invOp, NOARG16 }, +/* 0x31 */ { invOp, NOARG16 }, +/* 0x32 */ { invOp, NOARG16 }, +/* 0x33 */ { invOp, NOARG16 }, +/* 0x34 */ { invOp, NOARG16 }, +/* 0x35 */ { invOp, NOARG16 }, +/* 0x36 */ { invOp, NOARG16 }, +/* 0x37 */ { invOp, NOARG16 }, +/* 0x38 */ { invOp, NOARG16 }, + +/* System Functions (No stack arguments) */ + +/* 0x39 */ { invOp, NOARG16 }, +/* 0x3a */ { invOp, NOARG16 }, +/* 0x3b */ { invOp, NOARG16 }, +/* 0x3c */ { invOp, NOARG16 }, +/* 0x3d */ { invOp, NOARG16 }, +/* 0x3e */ { invOp, NOARG16 }, +/* 0x3f */ { "EXIT ", NOARG16 }, + +/************** OPCODES WITH SINGLE BYTE ARGUMENT (arg8) ***************/ + +/* 0x40 */ { invOp, NOARG16 }, +/* 0x41 */ { invOp, NOARG16 }, +/* 0x42 */ { invOp, NOARG16 }, +/* 0x43 */ { invOp, NOARG16 }, +/* 0x44 */ { invOp, NOARG16 }, +/* 0x45 */ { invOp, NOARG16 }, +/* 0x46 */ { invOp, NOARG16 }, +/* 0x47 */ { invOp, NOARG16 }, +/* 0x48 */ { invOp, NOARG16 }, +/* 0x49 */ { invOp, NOARG16 }, +/* 0x4a */ { invOp, NOARG16 }, +/* 0x4b */ { invOp, NOARG16 }, +/* 0x4c */ { invOp, NOARG16 }, +/* 0x4d */ { invOp, NOARG16 }, +/* 0x4e */ { invOp, NOARG16 }, +/* 0x4f */ { invOp, NOARG16 }, + +/* 0x50 */ { invOp, NOARG16 }, +/* 0x51 */ { invOp, NOARG16 }, +/* 0x52 */ { invOp, NOARG16 }, +/* 0x53 */ { invOp, NOARG16 }, +/* 0x54 */ { invOp, NOARG16 }, +/* 0x55 */ { invOp, NOARG16 }, +/* 0x56 */ { invOp, NOARG16 }, +/* 0x57 */ { invOp, NOARG16 }, +/* 0x58 */ { invOp, NOARG16 }, +/* 0x59 */ { invOp, NOARG16 }, +/* 0x5a */ { invOp, NOARG16 }, +/* 0x5b */ { invOp, NOARG16 }, +/* 0x5c */ { invOp, NOARG16 }, +/* 0x5d */ { invOp, NOARG16 }, +/* 0x5e */ { invOp, NOARG16 }, +/* 0x5f */ { invOp, NOARG16 }, + +/* Data stack: arg8 = 8 bit unsigned data (no stack arguments) */ + +/* 0x60 */ { invOp, NOARG16 }, +/* 0x61 */ { invOp, NOARG16 }, +/* 0x62 */ { invOp, NOARG16 }, +/* 0x63 */ { invOp, NOARG16 }, +/* 0x64 */ { invOp, NOARG16 }, +/* 0x65 */ { invOp, NOARG16 }, +/* 0x66 */ { invOp, NOARG16 }, +/* 0x67 */ { invOp, NOARG16 }, +/* 0x68 */ { invOp, NOARG16 }, +/* 0x69 */ { invOp, NOARG16 }, +/* 0x6a */ { invOp, NOARG16 }, +/* 0x6b */ { invOp, NOARG16 }, +/* 0x6c */ { invOp, NOARG16 }, +/* 0x6d */ { invOp, NOARG16 }, +/* 0x6e */ { invOp, NOARG16 }, +/* 0x6f */ { invOp, NOARG16 }, + +/* Floating Point Operations: arg8 = FP op-code */ + +/* 0x70 */ { "FLOAT", fpOP }, +/* 0x71 */ { invOp, NOARG16 }, +/* 0x72 */ { invOp, NOARG16 }, +/* 0x73 */ { invOp, NOARG16 }, +/* 0x74 */ { "PUSHB", NOARG16 }, +/* 0x75 */ { invOp, NOARG16 }, +/* 0x76 */ { invOp, NOARG16 }, +/* 0x77 */ { invOp, NOARG16 }, + +/* 0x78 */ { invOp, NOARG16 }, +/* 0x79 */ { invOp, NOARG16 }, +/* 0x7a */ { invOp, NOARG16 }, +/* 0x7b */ { invOp, NOARG16 }, +/* 0x7c */ { invOp, NOARG16 }, +/* 0x7d */ { invOp, NOARG16 }, +/* 0x7e */ { invOp, NOARG16 }, +/* 0x7f */ { invOp, NOARG16 }, + +/************ OPCODES WITH SINGLE 16-BIT ARGUMENT (arg16) ************/ + +/* 0x80 */ { invOp, NOARG16 }, +/* 0x81 */ { invOp, NOARG16 }, +/* 0x82 */ { invOp, NOARG16 }, +/* 0x83 */ { invOp, NOARG16 }, +/* 0x84 */ { invOp, NOARG16 }, +/* 0x85 */ { invOp, NOARG16 }, +/* 0x86 */ { invOp, NOARG16 }, +/* 0x87 */ { invOp, NOARG16 }, +/* 0x88 */ { invOp, NOARG16 }, +/* 0x89 */ { invOp, NOARG16 }, +/* 0x8a */ { invOp, NOARG16 }, +/* 0x8b */ { invOp, NOARG16 }, +/* 0x8c */ { invOp, NOARG16 }, +/* 0x8d */ { invOp, NOARG16 }, +/* 0x8e */ { invOp, NOARG16 }, +/* 0x8f */ { invOp, NOARG16 }, + +/* Program control: arg16 = unsigned label (One stack argument) */ + +/* 0x90 */ { "JEQUZ", HEX }, +/* 0x91 */ { "JNEQZ", HEX }, +/* 0x92 */ { "JLTZ ", HEX }, +/* 0x93 */ { "JGTEZ", HEX }, +/* 0x94 */ { "JGTZ ", HEX }, +/* 0x95 */ { "JLTEZ", HEX }, + +/* Program control: arg16 = unsigned label (no stack arguments) */ + +/* 0x96 */ { "JMP ", HEX }, +/* 0x97 */ { invOp, NOARG16 }, + +/* Program control: arg16 = unsigned label (One stack argument) */ + +/* 0x98 */ { "JEQU ", HEX }, +/* 0x99 */ { "JNEQ ", HEX }, +/* 0x9a */ { "JLT ", HEX }, +/* 0x9b */ { "JGTE ", HEX }, +/* 0x9c */ { "JGT ", HEX }, +/* 0x9d */ { "JLTE ", HEX }, +/* 0x9e */ { invOp, NOARG16 }, +/* 0x9f */ { invOp, NOARG16 }, + +/* Data stack: arg16 = 16 bit signed data (no stack arguments) */ + +/* Load: arg16 = unsigned base offset (no stack arguments) */ + +/* 0xa0 */ { "LD ", UDECIMAL }, +/* 0xa1 */ { "LDH ", UDECIMAL }, +/* 0xa2 */ { "LDB ", UDECIMAL }, +/* 0xa3 */ { "LDM ", UDECIMAL }, + +/* Store: arg16 = unsigned base offset (One stack arguments) */ + +/* 0xa4 */ { "ST ", UDECIMAL }, +/* 0xa5 */ { "STH ", UDECIMAL }, +/* 0xa6 */ { "STB ", UDECIMAL }, +/* 0xa7 */ { "STM ", UDECIMAL }, + +/* Load Indexed: arg16 = unsigned base offset (One stack arguments) */ + +/* 0xa8 */ { "LDX ", UDECIMAL }, +/* 0xa9 */ { "LDXH ", UDECIMAL }, +/* 0xaa */ { "LDXB ", UDECIMAL }, +/* 0xab */ { "LDXM ", UDECIMAL }, + +/* Store Indexed: arg16 = unsigned base offset (Two stack arguments) */ + +/* 0xac */ { "STX ", UDECIMAL }, +/* 0xad */ { "STXH ", UDECIMAL }, +/* 0xae */ { "STXB ", UDECIMAL }, +/* 0xaf */ { "STXM ", UDECIMAL }, + +/* 0xb0 */ { "LA ", UDECIMAL }, +/* 0xb1 */ { "LAC ", HEX, }, +/* 0xb2 */ { invOp, NOARG16 }, +/* 0xb3 */ { invOp, NOARG16 }, +/* 0xb4 */ { "PUSH ", DECIMAL }, +/* 0xb5 */ { "INDS ", DECIMAL }, +/* 0xb6 */ { invOp, NOARG16 }, +/* 0xb7 */ { invOp, NOARG16 }, +/* 0xb8 */ { "LAX ", UDECIMAL }, + +/* System operations: arg16 = 16-bit library function identifer */ + +/* 0xb9 */ { "LIB ", lbOP, }, +/* 0xba */ { invOp, NOARG16 }, +/* 0xbb */ { invOp, NOARG16 }, +/* 0xbc */ { invOp, NOARG16 }, +/* 0xbd */ { invOp, NOARG16 }, +/* 0xbe */ { invOp, NOARG16 }, + +/* Program control: arg16 = unsigned label (no stack arguments) */ + +/* 0xbf */ { "LABEL", LABEL_DEC }, + +/**** OPCODES WITH BYTE ARGUMENT (arg8) AND 16-BIT ARGUMENT (arg16) ****/ + +/* 0xc0 */ { invOp, NOARG16 }, +/* 0xc1 */ { invOp, NOARG16 }, +/* 0xc2 */ { invOp, NOARG16 }, +/* 0xc3 */ { invOp, NOARG16 }, +/* 0xc4 */ { invOp, NOARG16 }, +/* 0xc5 */ { invOp, NOARG16 }, +/* 0xc6 */ { invOp, NOARG16 }, +/* 0xc7 */ { invOp, NOARG16 }, + +/* Program Control: arg8 = level; arg16 = unsigned label (No stack + * arguments */ + +/* 0xc8 */ { "PCAL ", HEX }, +/* 0xc9 */ { invOp, NOARG16 }, +/* 0xca */ { invOp, NOARG16 }, +/* 0xcb */ { invOp, NOARG16 }, +/* 0xcc */ { invOp, NOARG16 }, +/* 0xcd */ { invOp, NOARG16 }, +/* 0xce */ { invOp, NOARG16 }, +/* 0xcf */ { invOp, NOARG16 }, + +/* 0xd0 */ { invOp, NOARG16 }, +/* 0xd1 */ { invOp, NOARG16 }, +/* 0xd2 */ { invOp, NOARG16 }, +/* 0xd3 */ { invOp, NOARG16 }, +/* 0xd4 */ { invOp, NOARG16 }, +/* 0xd5 */ { invOp, NOARG16 }, +/* 0xd6 */ { invOp, NOARG16 }, +/* 0xd7 */ { invOp, NOARG16 }, +/* 0xd8 */ { invOp, NOARG16 }, +/* 0xd9 */ { invOp, NOARG16 }, +/* 0xda */ { invOp, NOARG16 }, +/* 0xdb */ { invOp, NOARG16 }, +/* 0xdc */ { invOp, NOARG16 }, +/* 0xdd */ { invOp, NOARG16 }, +/* 0xde */ { invOp, NOARG16 }, +/* 0xdf */ { invOp, NOARG16 }, + +/* Load: arg8 = level; arg16 = signed frame offset (no stack arguments) */ + +/* 0xe0 */ { "LDS ", DECIMAL }, +/* 0xe1 */ { "LDSH ", DECIMAL }, +/* 0xe2 */ { "LDSB ", DECIMAL }, +/* 0xe3 */ { "LDSM ", DECIMAL }, + +/* Store: arg8 = level; arg16 = signed frame offset (One stack arguments) */ + +/* 0xe4 */ { "STS ", DECIMAL }, +/* 0xe5 */ { "STSH ", DECIMAL }, +/* 0xe6 */ { "STSB ", DECIMAL }, +/* 0xe7 */ { "STSM ", DECIMAL }, + +/* Load Indexed: arg8 = level; arg16 = signed frame offset (One stack arguments) */ + +/* 0xe8 */ { "LDSX ", DECIMAL }, +/* 0xe9 */ { "LDSXH", DECIMAL }, +/* 0xea */ { "LDSXB", DECIMAL }, +/* 0xeb */ { "LDSXM", DECIMAL }, + +/* Store Indexed: arg8 = level; arg16 = signed frame offset (Two stack arguments) */ + +/* 0xec */ { "STSX ", DECIMAL }, +/* 0xed */ { "STSXH", DECIMAL }, +/* 0xee */ { "STSXB", DECIMAL }, +/* 0xef */ { "STSXM", DECIMAL }, + +/* Load Address: arg8 = level; arg16 = signed frame offset (no stack arguments) */ + +/* 0xf0 */ { "LAS ", DECIMAL }, +/* 0xf1 */ { invOp, NOARG16 }, +/* 0xf2 */ { invOp, NOARG16 }, +/* 0xf3 */ { invOp, NOARG16 }, +/* 0xf4 */ { invOp, NOARG16 }, +/* 0xf5 */ { invOp, NOARG16 }, +/* 0xf6 */ { invOp, NOARG16 }, +/* 0xf7 */ { invOp, NOARG16 }, +/* 0xf8 */ { "LASX ", DECIMAL }, + +/* System Functions: (No stack arguments) + * For SYSIO: arg8 = file number; arg16 = sub-function code + */ + +/* 0xf9 */ { "SYSIO", xOP, }, +/* 0xfa */ { invOp, NOARG16 }, +/* 0xfb */ { invOp, NOARG16 }, +/* 0xfc */ { invOp, NOARG16 }, +/* 0xfd */ { invOp, NOARG16 }, +/* 0xfe */ { invOp, NOARG16 }, + +/* Psuedo-operations: + * For LINE: arg8 = file number; arg16 = line number + */ + +/* 0xff */ { "LINE ", COMMENT }, +}; + +static const char invXOp[] = "Invalid SYSIO"; +static const char *xName[MAX_XOP] = { /* SYSIO opcode mnemonics */ +/* 0x00 */ invXOp, "EOF", "EOLN", "RESET", +/* 0x04 */ "REWRITE", invXOp, invXOp, invXOp, +/* 0x08 */ invXOp, invXOp, invXOp, invXOp, +/* 0x0c */ invXOp, invXOp, invXOp, invXOp, +/* 0x10 */ "READLN", "READPG", "READBIN", "READINT", +/* 0x14 */ "READCHR", "READSTR", "READRL", invXOp, +/* 0x18 */ invXOp, invXOp, invXOp, invXOp, +/* 0x1c */ invXOp, invXOp, invXOp, invXOp, +/* 0x20 */ "WRITELN", "WRITEPG", "WRITEBIN", "WRITEINT", +/* 0x24 */ "WRITECHR", "WRITESTR", "WRITERL" }; + +static const char invLbOp[] = "Invalid runtime code"; +static const char *lbName[MAX_LBOP] = { /* LIB opcode mnemonics */ +/* 0x00 */ "GETENV", "STR2STR", "CSTR2STR", "STR2RSTR", +/* 0x04 */ "CSTR2RSTR", "VAL", "MKSTK", "MKSTKSTR", +/* 0x08 */ "MKSTKC", "STRCAT", "STRCATC", "STRCMP" }; + +static const char invFpOp[] = "Invalid FP Operation"; +static const char *fpName[MAX_FOP] = { +/* 0x00 */ invFpOp, "FLOAT", "TRUNC", "ROUND", +/* 0x04 */ "ADD", "SUB", "MUL", "DIV", +/* 0x08 */ "MOD", invFpOp, "EQU", "NEQ", +/* 0x0c */ "LT", "GTE", "GT", "LTE", +/* 0x10 */ "NEG", "ABS", "SQR", "SQRT", +/* 0x14 */ "SIN", "COS", "ATAN", "LN", +/* 0x18 */ "EXP" }; + +/***********************************************************************/ + +void insn_DisassemblePCode(FILE* lfile, OPTYPE *pop) +{ + /* Indent, comment or label */ + + switch (opTable[pop->op].format) + { + case LABEL_DEC : + fprintf(lfile, "L%04x: ", pop->arg2); + break; + case COMMENT : + fprintf(lfile, "; "); + break; + default : + fprintf(lfile, " "); + } /* end switch */ + + /* Special Case Comment line format */ + + if (opTable[pop->op].format == COMMENT) + { + fprintf(lfile, "%s ", opTable[pop->op].opName); + if (pop->op & o8) + { + fprintf(lfile, "%d", pop->arg1); + if (pop->op & o16) + fprintf(lfile, ":%d", pop->arg2); + } /* end if */ + else if (pop->op & o16) + fprintf(lfile, "%d", pop->arg2); + } /* end if */ + + /* Print normal opCode mnemonic */ + + else + { + fprintf(lfile, "%s ", opTable[pop->op].opName); + + /* Print pop->arg1 (if present) */ + + if (pop->op & o8) fprintf(lfile, "%d", pop->arg1); + + /* Print ar16 (if present) */ + + if (pop->op & o16) + { + switch (opTable[pop->op].format) + { + case HEX : + if (pop->op & o8) fprintf(lfile, ", "); + fprintf(lfile, "0x%04x", pop->arg2); + break; + + case COMMENT : + case DECIMAL : + if (pop->op & o8) fprintf(lfile, ", "); + fprintf(lfile, "%ld", signExtend16(pop->arg2)); + break; + + case UDECIMAL : + if (pop->op & o8) fprintf(lfile, ", "); + fprintf(lfile, "%u", pop->arg2); + break; + + case fpOP : + if ((pop->arg1 & fpMASK) < MAX_FOP) + fprintf(lfile, " %s", fpName[(pop->arg1 & 0x3f)]); + else + fprintf(lfile, " %s", invFpOp); + break; + + case xOP : + if (pop->arg2 < MAX_XOP) + fprintf(lfile, ", %s", xName[pop->arg2]); + else + fprintf(lfile, ", %s", invXOp); + break; + + case lbOP : + if (pop->arg2 < MAX_LBOP) + fprintf(lfile, "%s", lbName[pop->arg2]); + else + fprintf(lfile, "%s", invLbOp); + break; + + case LABEL_DEC : + default : + break; + } /* end switch */ + } /* end if */ + } /* end else */ + + /* Don't forget the newline! */ + + fputc('\n', lfile); + +} /* end dissassemblePcode */ + +/***********************************************************************/ diff --git a/misc/pascal/insn16/libinsn/pgen.c b/misc/pascal/insn16/libinsn/pgen.c index cc192587c..818bc907f 100644 --- a/misc/pascal/insn16/libinsn/pgen.c +++ b/misc/pascal/insn16/libinsn/pgen.c @@ -1,311 +1,312 @@ -/********************************************************************** - * pgen.c - * P-Code generation logic - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include -#include -#include - -#include "config.h" /* Configuration */ -#include "keywords.h" /* Standard types */ -#include "pdefs.h" /* Common types */ -#include "pofflib.h" /* POFF library definitions */ -#include "podefs.h" /* Logical opcode definitions */ -#include "pedefs.h" /* Error codes */ -#include "pinsn16.h" /* 16-bit target INSN opcode definitions */ -#include "perr.h" /* Error handling logic */ - -#include "pinsn.h" /* (to verify prototypes in this file) */ - -/********************************************************************** - * Definitions - **********************************************************************/ - -/********************************************************************** - * Global Variables - **********************************************************************/ - -extern poffHandle_t poffHandle; /* Handle to POFF object */ -extern FILE *lstFile; /* LIST file pointer */ -extern sint16 level; /* Static nesting level */ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -static const uint16 opmap[NUM_OPCODES] = -{ - oNOP, /* opNOP */ - oNEG, /* opNEG */ - oABS, /* opABS */ - oINC, /* opINC */ - oDEC, /* opDEC */ - oNOT, /* opNOT */ - oADD, /* opADD */ - oSUB, /* opSUB */ - oMUL, /* opMUL */ - oDIV, /* opDIV */ - oMOD, /* opMOD */ - oSLL, /* opSLL */ - oSRL, /* opSRL */ - oSRA, /* opSRA */ - oOR, /* opOR */ - oAND, /* opAND */ - oEQUZ, /* opEQUZ */ - oNEQZ, /* opNEQZ */ - oLTZ, /* opLTZ */ - oGTEZ, /* opGTEZ */ - oGTZ, /* opGTZ */ - oLTEZ, /* opLTEZ */ - oEQU, /* opEQU */ - oNEQ, /* opNEQ */ - oLT, /* opLT */ - oGTE, /* opGTE */ - oGT, /* opGT */ - oLTE, /* opLTE */ - oBIT, /* opBIT */ - oLDIH, /* opLDI -- integer load maps to 16-bit load */ - oLDIB, /* opLDIB */ - oLDIM, /* opLDIM */ - oSTIH, /* opSTI - integer store maps to 16-bit store */ - oSTIB, /* opSTIB */ - oSTIM, /* opSTIM */ - oDUPH, /* opDUP -- integer duplicate maps to 16-bit duplicate */ - oPUSHS, /* opPUSHS */ - oPOPS, /* opPOPS */ - oRET, /* opRET */ - oEND, /* opEND */ - oFLOAT, /* opFLOAT */ - oJEQUZ, /* opJEQUZ */ - oJNEQZ, /* opJNEQZ */ - oJMP, /* opJMP */ - oJEQU, /* opJEQU */ - oJNEQ, /* opJNEQ */ - oJLT, /* opJLT */ - oJGTE, /* opJGTE */ - oJGT, /* opJGT */ - oJLTE, /* opJLTE */ - oLDH, /* opLD -- integer load maps to 16-bit load */ - oLDH, /* opLDH */ - oLDB, /* opLDB */ - oLDM, /* opLDM */ - oSTH, /* opST -- integer store maps to 16-bit store */ - oSTB, /* opSTB */ - oSTM, /* opSTM */ - oLDXH, /* opLDX -- integer load maps to 16-bit load */ - oLDXB, /* opLDXB */ - oLDXM, /* opLDXM */ - oSTXH, /* opSTX -- integer store maps to 16-bit store */ - oSTXB, /* opSTXB */ - oSTXM, /* opSTXM */ - oLA, /* opLA */ - oLAC, /* opLAC */ - oPUSH, /* opPUSH */ - oINDS, /* opINDS */ - oLAX, /* opLAX */ - oLIB, /* opLIB */ - oLABEL, /* opLABEL */ - oPCAL, /* opPCAL */ - oLDSH, /* opLDS -- integer store maps to 16-bit load */ - oLDSH, /* opLDSH */ - oLDSB, /* opLDSB */ - oLDSM, /* opLDSM */ - oSTSH, /* opSTS -- integer store maps to 16-bit store */ - oSTSB, /* opSTSB */ - oSTSM, /* opSTSM */ - oLDSXH, /* opLDSX -- integer load maps to 16-bit load */ - oLDSXB, /* opLDSXB */ - oLDSXM, /* opLDSXM */ - oSTSXH, /* opSTSX -- integer store maps to 16-bit store */ - oSTSXB, /* opSTSXB */ - oSTSXM, /* opSTSXM */ - oLAS, /* opLAS */ - oLASX, /* opLASX */ - oSYSIO, /* opSYSIO */ - oLINE, /* opLINE */ -}; - -/*********************************************************************** - * Private Function Prototypes - ***********************************************************************/ - -/*********************************************************************** - * Private Functions - ***********************************************************************/ - -static void -insn16_Generate(enum pcode_e opcode, uint16 arg1, sint32 arg2); - -/*********************************************************************** - * Private Functions - ***********************************************************************/ - -/***********************************************************************/ -/* Disassemble an Op-code */ - -#if CONFIG_DEBUG -static inline void -insn16_DisassemblePCode(ubyte opcode, ubyte arg1, uint16 arg2) -{ - OPTYPE op; - - op.op = opcode; - op.arg1 = arg1; - op.arg2 = arg2; - - insn_DisassemblePCode(lstFile, &op); -} -#else -# define insn16_DisassemblePCode(op,a1,a2) -#endif - -/***********************************************************************/ -/* Generate an Op-Code */ - -static void -insn16_Generate(enum pcode_e opcode, uint16 arg1, sint32 arg2) -{ - uint16 insn_opcode = opmap[opcode]; - uint16 arg16; - TRACE(lstFile,"[insn16_Generate:0x%02x->0x%04x]", opcode, insn_opcode); - - poffAddProgByte(poffHandle, insn_opcode); - if (insn_opcode & o8) - { - if (arg1 > 0xff) error(eINTOVF); - poffAddProgByte(poffHandle, (ubyte)arg1); - } /* End if */ - - if (insn_opcode & o16) - { - if ((arg2 < -32768) || (arg2 > 65535)) error(eINTOVF); - arg16 = (uint16)arg2; - poffAddProgByte(poffHandle, (ubyte)(arg16 >> 8)); - poffAddProgByte(poffHandle, (ubyte)(arg16 & 0xff)); - } /* End if */ - - /* Now, add the disassembled PCode to the list file. */ - - insn16_DisassemblePCode(insn_opcode, arg1, arg2); - -} /* end insn16_Generate */ - -/*********************************************************************** - * Public Functions - ***********************************************************************/ - -void -insn_GenerateSimple(enum pcode_e opcode) -{ - insn16_Generate(opcode, 0, 0); -} - -/***********************************************************************/ - -void -insn_GenerateDataOperation(enum pcode_e opcode, sint32 data) -{ - insn16_Generate(opcode, 0, data); -} - -/***********************************************************************/ -/* Data size for a multiple register operation (in bytes) is simply - * represented by that value at the top of the stack. - */ - -void insn_GenerateDataSize(uint32 dwDataSize) -{ - insn16_Generate(opPUSH, 0, dwDataSize); -} - -/***********************************************************************/ - -void -insn_GenerateFpOperation(ubyte fpOpcode) -{ - insn16_Generate(opFLOAT, fpOpcode, 0); -} - -/***********************************************************************/ - -void -insn_GenerateIoOperation(uint16 ioOpcode, uint16 fileNumber) -{ - insn16_Generate(opSYSIO, fileNumber, (sint32)ioOpcode); -} - -/***********************************************************************/ - -void -insn_BuiltInFunctionCall(uint16 libOpcode) -{ - insn16_Generate(opLIB, 0, (sint32)libOpcode); -} - -/***********************************************************************/ - -void -insn_GenerateLevelReference(enum pcode_e opcode, uint16 level, sint32 offset) -{ - insn16_Generate(opcode, level, offset); -} - -/***********************************************************************/ - -void -insn_GenerateProcedureCall(uint16 level, sint32 offset) -{ - insn16_Generate(opPCAL, level, offset); -} - -/***********************************************************************/ - -void -insn_GenerateLineNumber(uint16 includeNumber, uint32 lineNumber) -{ - insn16_Generate(opLINE, includeNumber, lineNumber); -} - -/***********************************************************************/ - -void -insn_SetStackLevel(uint32 level) -{ - /* Do nothing */ -} +/********************************************************************** + * pgen.c + * P-Code generation logic + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include +#include +#include + +#include "config.h" /* Configuration */ +#include "keywords.h" /* Standard types */ +#include "pdefs.h" /* Common types */ +#include "pofflib.h" /* POFF library definitions */ +#include "podefs.h" /* Logical opcode definitions */ +#include "pedefs.h" /* Error codes */ +#include "pinsn16.h" /* 16-bit target INSN opcode definitions */ +#include "perr.h" /* Error handling logic */ + +#include "pinsn.h" /* (to verify prototypes in this file) */ + +/********************************************************************** + * Definitions + **********************************************************************/ + +/********************************************************************** + * Global Variables + **********************************************************************/ + +extern poffHandle_t poffHandle; /* Handle to POFF object */ +extern FILE *lstFile; /* LIST file pointer */ +extern int16_t level; /* Static nesting level */ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +static const uint16_t opmap[NUM_OPCODES] = +{ + oNOP, /* opNOP */ + oNEG, /* opNEG */ + oABS, /* opABS */ + oINC, /* opINC */ + oDEC, /* opDEC */ + oNOT, /* opNOT */ + oADD, /* opADD */ + oSUB, /* opSUB */ + oMUL, /* opMUL */ + oDIV, /* opDIV */ + oMOD, /* opMOD */ + oSLL, /* opSLL */ + oSRL, /* opSRL */ + oSRA, /* opSRA */ + oOR, /* opOR */ + oAND, /* opAND */ + oEQUZ, /* opEQUZ */ + oNEQZ, /* opNEQZ */ + oLTZ, /* opLTZ */ + oGTEZ, /* opGTEZ */ + oGTZ, /* opGTZ */ + oLTEZ, /* opLTEZ */ + oEQU, /* opEQU */ + oNEQ, /* opNEQ */ + oLT, /* opLT */ + oGTE, /* opGTE */ + oGT, /* opGT */ + oLTE, /* opLTE */ + oBIT, /* opBIT */ + oLDIH, /* opLDI -- integer load maps to 16-bit load */ + oLDIB, /* opLDIB */ + oLDIM, /* opLDIM */ + oSTIH, /* opSTI - integer store maps to 16-bit store */ + oSTIB, /* opSTIB */ + oSTIM, /* opSTIM */ + oDUPH, /* opDUP -- integer duplicate maps to 16-bit duplicate */ + oPUSHS, /* opPUSHS */ + oPOPS, /* opPOPS */ + oRET, /* opRET */ + oEND, /* opEND */ + oFLOAT, /* opFLOAT */ + oJEQUZ, /* opJEQUZ */ + oJNEQZ, /* opJNEQZ */ + oJMP, /* opJMP */ + oJEQU, /* opJEQU */ + oJNEQ, /* opJNEQ */ + oJLT, /* opJLT */ + oJGTE, /* opJGTE */ + oJGT, /* opJGT */ + oJLTE, /* opJLTE */ + oLDH, /* opLD -- integer load maps to 16-bit load */ + oLDH, /* opLDH */ + oLDB, /* opLDB */ + oLDM, /* opLDM */ + oSTH, /* opST -- integer store maps to 16-bit store */ + oSTB, /* opSTB */ + oSTM, /* opSTM */ + oLDXH, /* opLDX -- integer load maps to 16-bit load */ + oLDXB, /* opLDXB */ + oLDXM, /* opLDXM */ + oSTXH, /* opSTX -- integer store maps to 16-bit store */ + oSTXB, /* opSTXB */ + oSTXM, /* opSTXM */ + oLA, /* opLA */ + oLAC, /* opLAC */ + oPUSH, /* opPUSH */ + oINDS, /* opINDS */ + oLAX, /* opLAX */ + oLIB, /* opLIB */ + oLABEL, /* opLABEL */ + oPCAL, /* opPCAL */ + oLDSH, /* opLDS -- integer store maps to 16-bit load */ + oLDSH, /* opLDSH */ + oLDSB, /* opLDSB */ + oLDSM, /* opLDSM */ + oSTSH, /* opSTS -- integer store maps to 16-bit store */ + oSTSB, /* opSTSB */ + oSTSM, /* opSTSM */ + oLDSXH, /* opLDSX -- integer load maps to 16-bit load */ + oLDSXB, /* opLDSXB */ + oLDSXM, /* opLDSXM */ + oSTSXH, /* opSTSX -- integer store maps to 16-bit store */ + oSTSXB, /* opSTSXB */ + oSTSXM, /* opSTSXM */ + oLAS, /* opLAS */ + oLASX, /* opLASX */ + oSYSIO, /* opSYSIO */ + oLINE, /* opLINE */ +}; + +/*********************************************************************** + * Private Function Prototypes + ***********************************************************************/ + +/*********************************************************************** + * Private Functions + ***********************************************************************/ + +static void +insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2); + +/*********************************************************************** + * Private Functions + ***********************************************************************/ + +/***********************************************************************/ +/* Disassemble an Op-code */ + +#if CONFIG_DEBUG +static inline void +insn16_DisassemblePCode(uint8_t opcode, uint8_t arg1, uint16_t arg2) +{ + OPTYPE op; + + op.op = opcode; + op.arg1 = arg1; + op.arg2 = arg2; + + insn_DisassemblePCode(lstFile, &op); +} +#else +# define insn16_DisassemblePCode(op,a1,a2) +#endif + +/***********************************************************************/ +/* Generate an Op-Code */ + +static void +insn16_Generate(enum pcode_e opcode, uint16_t arg1, int32_t arg2) +{ + uint16_t insn_opcode = opmap[opcode]; + uint16_t arg16; + TRACE(lstFile,"[insn16_Generate:0x%02x->0x%04x]", opcode, insn_opcode); + + poffAddProgByte(poffHandle, insn_opcode); + if (insn_opcode & o8) + { + if (arg1 > 0xff) error(eINTOVF); + poffAddProgByte(poffHandle, (uint8_t)arg1); + } /* End if */ + + if (insn_opcode & o16) + { + if ((arg2 < -32768) || (arg2 > 65535)) error(eINTOVF); + arg16 = (uint16_t)arg2; + poffAddProgByte(poffHandle, (uint8_t)(arg16 >> 8)); + poffAddProgByte(poffHandle, (uint8_t)(arg16 & 0xff)); + } /* End if */ + + /* Now, add the disassembled PCode to the list file. */ + + insn16_DisassemblePCode(insn_opcode, arg1, arg2); + +} /* end insn16_Generate */ + +/*********************************************************************** + * Public Functions + ***********************************************************************/ + +void +insn_GenerateSimple(enum pcode_e opcode) +{ + insn16_Generate(opcode, 0, 0); +} + +/***********************************************************************/ + +void +insn_GenerateDataOperation(enum pcode_e opcode, int32_t data) +{ + insn16_Generate(opcode, 0, data); +} + +/***********************************************************************/ +/* Data size for a multiple register operation (in bytes) is simply + * represented by that value at the top of the stack. + */ + +void insn_GenerateDataSize(uint32_t dwDataSize) +{ + insn16_Generate(opPUSH, 0, dwDataSize); +} + +/***********************************************************************/ + +void +insn_GenerateFpOperation(uint8_t fpOpcode) +{ + insn16_Generate(opFLOAT, fpOpcode, 0); +} + +/***********************************************************************/ + +void +insn_GenerateIoOperation(uint16_t ioOpcode, uint16_t fileNumber) +{ + insn16_Generate(opSYSIO, fileNumber, (int32_t)ioOpcode); +} + +/***********************************************************************/ + +void +insn_BuiltInFunctionCall(uint16_t libOpcode) +{ + insn16_Generate(opLIB, 0, (int32_t)libOpcode); +} + +/***********************************************************************/ + +void +insn_GenerateLevelReference(enum pcode_e opcode, uint16_t level, int32_t offset) +{ + insn16_Generate(opcode, level, offset); +} + +/***********************************************************************/ + +void +insn_GenerateProcedureCall(uint16_t level, int32_t offset) +{ + insn16_Generate(opPCAL, level, offset); +} + +/***********************************************************************/ + +void +insn_GenerateLineNumber(uint16_t includeNumber, uint32_t lineNumber) +{ + insn16_Generate(opLINE, includeNumber, lineNumber); +} + +/***********************************************************************/ + +void +insn_SetStackLevel(uint32_t level) +{ + /* Do nothing */ +} diff --git a/misc/pascal/insn16/libinsn/pgetopcode.c b/misc/pascal/insn16/libinsn/pgetopcode.c index b9167a016..cc6f93077 100644 --- a/misc/pascal/insn16/libinsn/pgetopcode.c +++ b/misc/pascal/insn16/libinsn/pgetopcode.c @@ -1,138 +1,140 @@ -/********************************************************************** - * pgetopcode.c - * P-Code access utilities - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include "keywords.h" -#include "podefs.h" -#include "pinsn16.h" - -#include "paslib.h" -#include "pofflib.h" -#include "pinsn.h" - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -/********************************************************************** - * Global Variables - **********************************************************************/ - -static sint16 g_bEndIn = 0; /* 1 = oEND pcode or EOF received */ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/********************************************************************** - * Private Functions - **********************************************************************/ - -/********************************************************************** - * Global Functions - **********************************************************************/ - -/**********************************************************************/ - -uint32 insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr) -{ - uint32 opsize = 1; - int c; - - TRACE(stderr, "[insn_GetOpCode]"); - - /* If we are not already at the EOF, read the next character from - * the input stream. - */ - - if (!g_bEndIn) - c = poffGetProgByte(handle); - else - c = EOF; - - /* Check for end of file. We may have previously parsed oEND which - * is a 'logical' end of file for a pascal program (but not a unit) - * or we may be at the physical end of the file wihout encountering - * oEND (typical for a UNIT file). - */ - - if ((g_bEndIn) || (c == EOF)) - { - ptr->op = oEND; - ptr->arg1 = 0; - ptr->arg2 = 0; - } /* end if */ - else - { - ptr->op = c; - g_bEndIn = (ptr->op == oEND); - - if (ptr->op & o8) - { - ptr->arg1 = poffGetProgByte(handle); - opsize++; - } - else - { - ptr->arg1 = 0; - } - - if (ptr->op & o16) - { - ptr->arg2 = (poffGetProgByte(handle) << 8); - ptr->arg2 |= (poffGetProgByte(handle) & 0xff); - opsize += 2; - } - else - { - ptr->arg2 = 0; - } - } - return opsize; -} - -/**********************************************************************/ - -void insn_ResetOpCodeRead(poffHandle_t handle) -{ - poffResetAccess(handle); - g_bEndIn = 0; -} - -/***********************************************************************/ +/********************************************************************** + * pgetopcode.c + * P-Code access utilities + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include + +#include "keywords.h" +#include "podefs.h" +#include "pinsn16.h" + +#include "paslib.h" +#include "pofflib.h" +#include "pinsn.h" + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +/********************************************************************** + * Global Variables + **********************************************************************/ + +static int16_t g_bEndIn = 0; /* 1 = oEND pcode or EOF received */ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +/********************************************************************** + * Private Functions + **********************************************************************/ + +/********************************************************************** + * Global Functions + **********************************************************************/ + +/**********************************************************************/ + +uint32_t insn_GetOpCode(poffHandle_t handle, OPTYPE *ptr) +{ + uint32_t opsize = 1; + int c; + + TRACE(stderr, "[insn_GetOpCode]"); + + /* If we are not already at the EOF, read the next character from + * the input stream. + */ + + if (!g_bEndIn) + c = poffGetProgByte(handle); + else + c = EOF; + + /* Check for end of file. We may have previously parsed oEND which + * is a 'logical' end of file for a pascal program (but not a unit) + * or we may be at the physical end of the file wihout encountering + * oEND (typical for a UNIT file). + */ + + if ((g_bEndIn) || (c == EOF)) + { + ptr->op = oEND; + ptr->arg1 = 0; + ptr->arg2 = 0; + } /* end if */ + else + { + ptr->op = c; + g_bEndIn = (ptr->op == oEND); + + if (ptr->op & o8) + { + ptr->arg1 = poffGetProgByte(handle); + opsize++; + } + else + { + ptr->arg1 = 0; + } + + if (ptr->op & o16) + { + ptr->arg2 = (poffGetProgByte(handle) << 8); + ptr->arg2 |= (poffGetProgByte(handle) & 0xff); + opsize += 2; + } + else + { + ptr->arg2 = 0; + } + } + return opsize; +} + +/**********************************************************************/ + +void insn_ResetOpCodeRead(poffHandle_t handle) +{ + poffResetAccess(handle); + g_bEndIn = 0; +} + +/***********************************************************************/ diff --git a/misc/pascal/insn16/libinsn/preloc.c b/misc/pascal/insn16/libinsn/preloc.c index 9db115c28..0ecb53cb4 100644 --- a/misc/pascal/insn16/libinsn/preloc.c +++ b/misc/pascal/insn16/libinsn/preloc.c @@ -1,147 +1,149 @@ -/********************************************************************** - * preloc.c - * Perform P-Code relocations - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include "keywords.h" -#include "pdefs.h" -#include "pedefs.h" -#include "podefs.h" -#include "pinsn16.h" - -#include "pofflib.h" -#include "perr.h" -#include "pinsn.h" - -/********************************************************************** - * Definitions - **********************************************************************/ - -/********************************************************************** - * Private Type Definitions - **********************************************************************/ - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -/********************************************************************** - * Global Variables - **********************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/********************************************************************** - * Private Functions - **********************************************************************/ - -int insn_Relocate(OPTYPE *op, uint32 pcOffset, uint32 roOffset) -{ - switch (op->op) - { - /* Catch each instruction that references the read-only data - * section. - */ - - case oLAC: - /* Add the offset to the read-only data section */ - - op->arg2 += roOffset; - break; - - /* Catch each instruction that references the text section - * data via an offset. - */ - - case oPCAL: /* Procedure / Function calls */ - case oJMP: /* Unconditional jump */ - case oJEQUZ: /* Jump on unary comparisons with zero */ - case oJNEQZ: - case oJLTZ: - case oJGTEZ: - case oJGTZ: - case oJLTEZ: - case oJEQU: /* Jump on binary comparisons */ - case oJNEQ: - case oJLT: - case oJGTE: - case oJGT: - case oJLTE: - /* Add the offset to the text section */ - - op->arg2 += pcOffset; - break; - - /* Return an end of file indication if oEND encountered */ - - case oEND: - return 1; - - /* Otherwise, it is not an interesting opcode */ - default: - break; - } - - /* Return 0 on all opcodes other than oEND */ - - return 0; -} - -/***********************************************************************/ - -void insn_FixupProcedureCall(ubyte *progData, uint32 symValue) -{ - - /* Sanity checking */ - - if (progData[0] != oPCAL) - fatal(ePOFFCONFUSION); - - if (symValue > 0xffff) - fatal(eBADSHORTINT); - - /* Perform the relocation */ - - progData[2] = symValue >> 8; - progData[3] = symValue & 0xff; -} - - -/***********************************************************************/ +/********************************************************************** + * preloc.c + * Perform P-Code relocations + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pedefs.h" +#include "podefs.h" +#include "pinsn16.h" + +#include "pofflib.h" +#include "perr.h" +#include "pinsn.h" + +/********************************************************************** + * Definitions + **********************************************************************/ + +/********************************************************************** + * Private Type Definitions + **********************************************************************/ + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +/********************************************************************** + * Global Variables + **********************************************************************/ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +/********************************************************************** + * Private Functions + **********************************************************************/ + +int insn_Relocate(OPTYPE *op, uint32_t pcOffset, uint32_t roOffset) +{ + switch (op->op) + { + /* Catch each instruction that references the read-only data + * section. + */ + + case oLAC: + /* Add the offset to the read-only data section */ + + op->arg2 += roOffset; + break; + + /* Catch each instruction that references the text section + * data via an offset. + */ + + case oPCAL: /* Procedure / Function calls */ + case oJMP: /* Unconditional jump */ + case oJEQUZ: /* Jump on unary comparisons with zero */ + case oJNEQZ: + case oJLTZ: + case oJGTEZ: + case oJGTZ: + case oJLTEZ: + case oJEQU: /* Jump on binary comparisons */ + case oJNEQ: + case oJLT: + case oJGTE: + case oJGT: + case oJLTE: + /* Add the offset to the text section */ + + op->arg2 += pcOffset; + break; + + /* Return an end of file indication if oEND encountered */ + + case oEND: + return 1; + + /* Otherwise, it is not an interesting opcode */ + default: + break; + } + + /* Return 0 on all opcodes other than oEND */ + + return 0; +} + +/***********************************************************************/ + +void insn_FixupProcedureCall(uint8_t *progData, uint32_t symValue) +{ + + /* Sanity checking */ + + if (progData[0] != oPCAL) + fatal(ePOFFCONFUSION); + + if (symValue > 0xffff) + fatal(eBADSHORTINT); + + /* Perform the relocation */ + + progData[2] = symValue >> 8; + progData[3] = symValue & 0xff; +} + + +/***********************************************************************/ diff --git a/misc/pascal/insn16/plist/plist.c b/misc/pascal/insn16/plist/plist.c index 581e9f769..538a17bc1 100644 --- a/misc/pascal/insn16/plist/plist.c +++ b/misc/pascal/insn16/plist/plist.c @@ -1,359 +1,360 @@ -/********************************************************************** - * plist.c - * POFF file lister - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include -#include -#include -#include -#include - -#define _GNU_SOURCE -#include - -#include "keywords.h" -#include "pdefs.h" -#include "podefs.h" -#include "pinsn16.h" -#include "pedefs.h" - -#include "pofflib.h" - -#include "paslib.h" -#include "pinsn.h" - -/********************************************************************** - * Definitions - **********************************************************************/ - -#define MAX_STRING 80 - -/********************************************************************** - * Private Data - **********************************************************************/ - -static char *poffFileName = NULL; -static int showFileHeader = 0; -static int showSectionHeaders = 0; -static int showSymbols = 0; -static int showRelocs = 0; -static int disassemble = 0; - -/********************************************************************** - * Private Constant Data - **********************************************************************/ - -static const struct option long_options[] = -{ - {"all", 0, NULL, 'a'}, - {"file-header", 0, NULL, 'h'}, - {"section-headers", 0, NULL, 'S'}, - {"symbols", 0, NULL, 's'}, - {"relocs", 0, NULL, 'r'}, - {"disassemble", 0, NULL, 'd'}, - {"help", 0, NULL, 'H'}, - {NULL, 0, NULL, 0} -}; - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -static void showUsage (const char *progname); -static void parseArgs (int argc, char **argv); -static void dumpProgramData (poffHandle_t poffHandle); - -/********************************************************************** - * Global Functions - **********************************************************************/ - -int main (int argc, char *argv[], char *envp[]) -{ - FILE *object; /* Object file pointer */ - poffHandle_t poffHandle; /* Handle for POFF object */ - char fileName[FNAME_SIZE+1]; /* Object file name */ - uint16 errCode; /* See pedefs.h */ - - /* Parse the command line arguments */ - - parseArgs(argc, argv); - - /* Open source POFF file -- Use .o or command line extension, if supplied */ - - (void) extension (poffFileName, "o", fileName, 0); - if (!(object = fopen (fileName, "rb"))) - { - printf ("Error opening %s\n", fileName); - exit (1); - } /* end if */ - - /* Read the POFF file */ - - poffHandle = poffCreateHandle(); - if (poffHandle == NULL) - { - printf ("Could not get POFF handler\n"); - exit (1); - } - - errCode = poffReadFile(poffHandle, object); - if (errCode != eNOERROR) - { - printf ("Could not read POFF file\n"); - exit (1); - } - - /* Dump the File Header */ - - if (showFileHeader) - { - poffDumpFileHeader(poffHandle, stdout); - } - - /* Dump the Section Headers */ - - if (showSectionHeaders) - { - poffDumpSectionHeaders(poffHandle, stdout); - } - - /* Dump the symbol table */ - - if (showSymbols) - { - poffDumpSymbolTable(poffHandle, stdout); - } - - /* Dump the relocation table */ - - if (showRelocs) - { - poffDumpRelocTable(poffHandle, stdout); - } - - /* Dump the program data section -- Main Loop */ - - if (disassemble) - { - dumpProgramData(poffHandle); - } - - /* Close files and release objects */ - - poffDestroyHandle(poffHandle); - (void)fclose(object); - return 0; -} /* end main */ - -/********************************************************************** - * Private Functions - **********************************************************************/ - -static void showUsage(const char *progname) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] \n", - progname); - fprintf(stderr, "options:\n"); - fprintf(stderr, " -a --all Equivalent to: -h -S -s -r -d\n"); - fprintf(stderr, " -h --file-header Display the POFF file header\n"); - fprintf(stderr, " -S --section-headers Display the sections' header\n"); - fprintf(stderr, " -s --symbols Display the symbol table\n"); - fprintf(stderr, " -r --relocs Display the relocations\n"); - fprintf(stderr, " -d --disassemble Display disassembled text\n"); - fprintf(stderr, " -H --help Display this information\n"); - exit(1); -} - -/***********************************************************************/ - -static void parseArgs(int argc, char **argv) -{ - int option_index; - int c; - - /* Check for existence of filename argument */ - - if (argc < 2) - { - fprintf(stderr, "ERROR: POFF filename required\n"); - showUsage(argv[0]); - } /* end if */ - - /* Parse the command line options */ - - do - { - c = getopt_long (argc, argv, "ahSsrdH", - long_options, &option_index); - if (c != -1) - { - switch (c) - { - case 'a' : - showFileHeader = 1; - showSectionHeaders = 1; - showSymbols = 1; - showRelocs = 1; - disassemble = 1; - break; - - case 'h' : - showFileHeader = 1; - break; - - case 'S' : - showSectionHeaders = 1; - break; - - case 's' : - showSymbols = 1; - break; - - case 'r' : - showRelocs = 1; - break; - - case 'd' : - disassemble = 1; - break; - - case 'H' : - showUsage(argv[0]); - break; - - default: - /* Shouldn't happen */ - - fprintf(stderr, "ERROR: Unrecognized option\n"); - showUsage(argv[0]); - } - } - } - while (c != -1); - - /* Get the name of the p-code file(s) from the last argument(s) */ - - if (optind != argc-1) - { - fprintf(stderr, "ERROR: POFF filename required as final argument\n"); - showUsage(argv[0]); - } - - /* Save the POFF file name */ - - poffFileName = argv[argc-1]; -} - -/***********************************************************************/ - -static void dumpProgramData(poffHandle_t poffHandle) -{ - poffLibLineNumber_t *lastln; /* Previous line number reference */ - poffLibLineNumber_t *ln; /* Current line number reference */ - uint32 pc; /* Program counter */ - OPTYPE op; /* Opcode */ - int opSize; /* Size of the opcode */ - int inch; /* Input char */ - - /* Read the line number entries from the POFF file */ - - poffReadLineNumberTable(poffHandle); - - /* Dump the program data section -- DumpProgramData Loop */ - - pc = 0; - lastln = NULL; - - while ((inch = poffGetProgByte(poffHandle)) != EOF) - { - /* Get opcode arguments (if any) */ - - op.op = (ubyte) inch; - op.arg1 = 0; - op.arg2 = 0; - opSize = 1; - - if (op.op & o8) - { - op.arg1 = poffGetProgByte(poffHandle); - opSize += 1; - } - - if (op.op & o16 ) - { - op.arg2 = poffGetProgByte(poffHandle) << 8; - op.arg2 |= poffGetProgByte(poffHandle); - opSize += 2; - } /* end if */ - - /* Find the line number associated with this line */ - - ln = poffFindLineNumber(pc); - if ((ln) && (ln != lastln)) - { - /* Print the line number line */ - - printf("\n%s:%ld\n", ln->filename, ln->lineno); - - /* This will suppress reporting the same line number - * repeatedly. - */ - - lastln = ln; - } - - /* Print the address then the opcode on stdout */ - - fprintf(stdout, "%08lx ", pc); - insn_DisassemblePCode(stdout, &op); - - /* Bump the PC to the next address */ - - pc += opSize; - - } /* end while */ - - /* Release buffers associated with line number information */ - - poffReleaseLineNumberTable(); - -} /* end dumpProgramData */ - -/***********************************************************************/ +/********************************************************************** + * plist.c + * POFF file lister + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE +#include + +#include "keywords.h" +#include "pdefs.h" +#include "podefs.h" +#include "pinsn16.h" +#include "pedefs.h" + +#include "pofflib.h" + +#include "paslib.h" +#include "pinsn.h" + +/********************************************************************** + * Definitions + **********************************************************************/ + +#define MAX_STRING 80 + +/********************************************************************** + * Private Data + **********************************************************************/ + +static char *poffFileName = NULL; +static int showFileHeader = 0; +static int showSectionHeaders = 0; +static int showSymbols = 0; +static int showRelocs = 0; +static int disassemble = 0; + +/********************************************************************** + * Private Constant Data + **********************************************************************/ + +static const struct option long_options[] = +{ + {"all", 0, NULL, 'a'}, + {"file-header", 0, NULL, 'h'}, + {"section-headers", 0, NULL, 'S'}, + {"symbols", 0, NULL, 's'}, + {"relocs", 0, NULL, 'r'}, + {"disassemble", 0, NULL, 'd'}, + {"help", 0, NULL, 'H'}, + {NULL, 0, NULL, 0} +}; + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +static void showUsage (const char *progname); +static void parseArgs (int argc, char **argv); +static void dumpProgramData (poffHandle_t poffHandle); + +/********************************************************************** + * Global Functions + **********************************************************************/ + +int main (int argc, char *argv[], char *envp[]) +{ + FILE *object; /* Object file pointer */ + poffHandle_t poffHandle; /* Handle for POFF object */ + char fileName[FNAME_SIZE+1]; /* Object file name */ + uint16_t errCode; /* See pedefs.h */ + + /* Parse the command line arguments */ + + parseArgs(argc, argv); + + /* Open source POFF file -- Use .o or command line extension, if supplied */ + + (void) extension (poffFileName, "o", fileName, 0); + if (!(object = fopen (fileName, "rb"))) + { + printf ("Error opening %s\n", fileName); + exit (1); + } /* end if */ + + /* Read the POFF file */ + + poffHandle = poffCreateHandle(); + if (poffHandle == NULL) + { + printf ("Could not get POFF handler\n"); + exit (1); + } + + errCode = poffReadFile(poffHandle, object); + if (errCode != eNOERROR) + { + printf ("Could not read POFF file\n"); + exit (1); + } + + /* Dump the File Header */ + + if (showFileHeader) + { + poffDumpFileHeader(poffHandle, stdout); + } + + /* Dump the Section Headers */ + + if (showSectionHeaders) + { + poffDumpSectionHeaders(poffHandle, stdout); + } + + /* Dump the symbol table */ + + if (showSymbols) + { + poffDumpSymbolTable(poffHandle, stdout); + } + + /* Dump the relocation table */ + + if (showRelocs) + { + poffDumpRelocTable(poffHandle, stdout); + } + + /* Dump the program data section -- Main Loop */ + + if (disassemble) + { + dumpProgramData(poffHandle); + } + + /* Close files and release objects */ + + poffDestroyHandle(poffHandle); + (void)fclose(object); + return 0; +} /* end main */ + +/********************************************************************** + * Private Functions + **********************************************************************/ + +static void showUsage(const char *progname) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s [options] \n", + progname); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -a --all Equivalent to: -h -S -s -r -d\n"); + fprintf(stderr, " -h --file-header Display the POFF file header\n"); + fprintf(stderr, " -S --section-headers Display the sections' header\n"); + fprintf(stderr, " -s --symbols Display the symbol table\n"); + fprintf(stderr, " -r --relocs Display the relocations\n"); + fprintf(stderr, " -d --disassemble Display disassembled text\n"); + fprintf(stderr, " -H --help Display this information\n"); + exit(1); +} + +/***********************************************************************/ + +static void parseArgs(int argc, char **argv) +{ + int option_index; + int c; + + /* Check for existence of filename argument */ + + if (argc < 2) + { + fprintf(stderr, "ERROR: POFF filename required\n"); + showUsage(argv[0]); + } /* end if */ + + /* Parse the command line options */ + + do + { + c = getopt_long (argc, argv, "ahSsrdH", + long_options, &option_index); + if (c != -1) + { + switch (c) + { + case 'a' : + showFileHeader = 1; + showSectionHeaders = 1; + showSymbols = 1; + showRelocs = 1; + disassemble = 1; + break; + + case 'h' : + showFileHeader = 1; + break; + + case 'S' : + showSectionHeaders = 1; + break; + + case 's' : + showSymbols = 1; + break; + + case 'r' : + showRelocs = 1; + break; + + case 'd' : + disassemble = 1; + break; + + case 'H' : + showUsage(argv[0]); + break; + + default: + /* Shouldn't happen */ + + fprintf(stderr, "ERROR: Unrecognized option\n"); + showUsage(argv[0]); + } + } + } + while (c != -1); + + /* Get the name of the p-code file(s) from the last argument(s) */ + + if (optind != argc-1) + { + fprintf(stderr, "ERROR: POFF filename required as final argument\n"); + showUsage(argv[0]); + } + + /* Save the POFF file name */ + + poffFileName = argv[argc-1]; +} + +/***********************************************************************/ + +static void dumpProgramData(poffHandle_t poffHandle) +{ + poffLibLineNumber_t *lastln; /* Previous line number reference */ + poffLibLineNumber_t *ln; /* Current line number reference */ + uint32_t pc; /* Program counter */ + OPTYPE op; /* Opcode */ + int opSize; /* Size of the opcode */ + int inch; /* Input char */ + + /* Read the line number entries from the POFF file */ + + poffReadLineNumberTable(poffHandle); + + /* Dump the program data section -- DumpProgramData Loop */ + + pc = 0; + lastln = NULL; + + while ((inch = poffGetProgByte(poffHandle)) != EOF) + { + /* Get opcode arguments (if any) */ + + op.op = (uint8_t) inch; + op.arg1 = 0; + op.arg2 = 0; + opSize = 1; + + if (op.op & o8) + { + op.arg1 = poffGetProgByte(poffHandle); + opSize += 1; + } + + if (op.op & o16 ) + { + op.arg2 = poffGetProgByte(poffHandle) << 8; + op.arg2 |= poffGetProgByte(poffHandle); + opSize += 2; + } /* end if */ + + /* Find the line number associated with this line */ + + ln = poffFindLineNumber(pc); + if ((ln) && (ln != lastln)) + { + /* Print the line number line */ + + printf("\n%s:%ld\n", ln->filename, ln->lineno); + + /* This will suppress reporting the same line number + * repeatedly. + */ + + lastln = ln; + } + + /* Print the address then the opcode on stdout */ + + fprintf(stdout, "%08lx ", pc); + insn_DisassemblePCode(stdout, &op); + + /* Bump the PC to the next address */ + + pc += opSize; + + } /* end while */ + + /* Release buffers associated with line number information */ + + poffReleaseLineNumberTable(); + +} /* end dumpProgramData */ + +/***********************************************************************/ diff --git a/misc/pascal/insn16/popt/pcopt.c b/misc/pascal/insn16/popt/pcopt.c index 5af19002c..5f8deed80 100644 --- a/misc/pascal/insn16/popt/pcopt.c +++ b/misc/pascal/insn16/popt/pcopt.c @@ -1,905 +1,906 @@ -/********************************************************************** - * pcopt.c - * Constant Expression Optimizations - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include - -#include "keywords.h" -#include "pdefs.h" -#include "pinsn16.h" - -#include "paslib.h" -#include "popt.h" -#include "polocal.h" -#include "pcopt.h" - -/**********************************************************************/ - -sint16 unaryOptimize(void) -{ - sint16 nchanges = 0; - register uint16 temp; - register sint16 i; - - TRACE(stderr, "[unaryOptimize]"); - - /* At least two pcodes are need to perform unary optimizations */ - - i = 0; - while (i < nops-1) - { - /* Check for a constant value being pushed onto the stack */ - - if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB)) - { - /* Turn the oPUSHB into an oPUSH op (temporarily) */ - - if (pptr[i]->op == oPUSHB) - { - pptr[i]->op = oPUSH; - pptr[i]->arg2 = pptr[i]->arg1; - pptr[i]->arg1 = 0; - } /* end if */ - - switch (pptr[i+1]->op) - { - /* Delete unary operators on constants */ - case oNEG : - pptr[i]->arg2 = -(pptr[i]->arg2); - deletePcode(i+1); - nchanges++; - break; - - case oABS : - if (signExtend16(pptr[i]->arg2) < 0) - pptr[i]->arg2 = -signExtend16(pptr[i]->arg2); - deletePcode(i+1); - nchanges++; - break; - - case oINC : - (pptr[i]->arg2)++; - deletePcode(i+1); - nchanges++; - break; - - case oDEC : - (pptr[i]->arg2)--; - deletePcode(i+1); - nchanges++; - break; - - case oNOT : - pptr[i]->arg2 = ~(pptr[i]->arg2); - deletePcode(i+1); - nchanges++; - break; - - /* Simplify binary operations on constants */ - - case oADD : - if (pptr[i]->arg2 == 0) - { - deletePcodePair(i, (i+1)); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i+1]->op = oINC; - deletePcode(i); - nchanges++; - } /* end else if */ - else if (pptr[i]->arg2 == (uint16)-1) - { - pptr[i+1]->op = oDEC; - deletePcode(i); - nchanges++; - } /* end else if */ - else i++; - break; - - case oSUB : - if (pptr[i]->arg2 == 0) - { - deletePcodePair(i, (i+1)); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i+1]->op = oDEC; - deletePcode(i); - nchanges++; - } /* end else if */ - else if (pptr[i]->arg2 == (uint16)-1) - { - pptr[i+1]->op = oINC; - deletePcode(i); - nchanges++; - } /* end else if */ - else i++; - break; - - case oMUL : - case oDIV : - temp = 0; - switch (pptr[i]->arg2) - { - case 1 : - deletePcodePair(i, (i+1)); - nchanges++; - break; - case 16384 : temp++; - case 8192 : temp++; - case 4096 : temp++; - case 2048 : temp++; - case 1024 : temp++; - case 512 : temp++; - case 256 : temp++; - case 128 : temp++; - case 64 : temp++; - case 32 : temp++; - case 16 : temp++; - case 8 : temp++; - case 4 : temp++; - case 2 : temp++; - pptr[i]->arg2 = temp; - if (pptr[i+1]->op == oMUL) - pptr[i+1]->op = oSLL; - else - pptr[i+1]->op = oSRA; - nchanges++; - i++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oSLL : - case oSRL : - case oSRA : - case oOR : - if (pptr[i]->arg2 == 0) - { - deletePcodePair(i, (i+1)); - nchanges++; - } /* end if */ - else i++; - break; - - case oAND : - if (pptr[i]->arg2 == 0xffff) - { - deletePcodePair(i, (i+1)); - nchanges++; - } /* end if */ - else i++; - break; - - /* Delete comparisons of constants to zero */ - - case oEQUZ : - if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1; - else pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - case oNEQZ : - if (pptr[i]->arg2 != 0) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - case oLTZ : - if (signExtend16(pptr[i]->arg2) < 0) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - case oGTEZ : - if (signExtend16(pptr[i]->arg2) >= 0) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - case oGTZ : - if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1; - else pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - case oLTEZ : - if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1; - else pptr[i]->arg2 = 0; - deletePcode(i+1); - nchanges++; - break; - - /* Simplify comparisons with certain constants */ - - case oEQU : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oEQUZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oEQUZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oEQUZ; - nchanges++; - } /* end else if */ - else i++; - break; - - case oNEQ : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oNEQZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oNEQZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oNEQZ; - nchanges++; - } /* end else if */ - else i++; - break; - - case oLT : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oLTZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oLTZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oLTZ; - nchanges++; - } /* end else if */ - else i++; - break; - - case oGTE : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oGTEZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oGTEZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oGTEZ; - nchanges++; - } /* end else if */ - else i++; - break; - - case oGT : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oGTZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oGTZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oGTZ; - nchanges++; - } /* end else if */ - else i++; - break; - - case oLTE : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oLTEZ; - deletePcode(i); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i]->op = oDEC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oLTEZ; - nchanges++; - } /* end else if */ - else if (signExtend16(pptr[i]->arg2) == -1) - { - pptr[i]->op = oINC; - pptr[i]->arg2 = 0; - pptr[i+1]->op = oLTEZ; - nchanges++; - } /* end else if */ - else i++; - break; - - /* Simplify or delete condition branches on constants */ - - case oJEQUZ : - if (pptr[i]->arg2 == 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - case oJNEQZ : - if (pptr[i]->arg2 != 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - case oJLTZ : - if (signExtend16(pptr[i]->arg2) < 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - case oJGTEZ : - if (signExtend16(pptr[i]->arg2) >= 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - case oJGTZ : - if (pptr[i]->arg2 > 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - case oJLTEZ : - if (pptr[i]->arg2 <= 0) - { - pptr[i+1]->op = oJMP; - deletePcode(i); - } /* end if */ - else - deletePcodePair(i, (i+1)); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - - /* If the oPUSH instruction is still there, see if we can now */ - /* represent it with an oPUSHB instruction */ - - if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) - { - pptr[i]->op = oPUSHB; - pptr[i]->arg1 = pptr[i]->arg2; - pptr[i]->arg2 = 0; - } /* end if */ - } /* end if */ - - /* Delete multiple modifications of DSEG pointer */ - - else if (pptr[i]->op == oINDS) - { - if (pptr[i+1]->op == oINDS) - { - pptr[i]->arg2 += pptr[i+1]->arg2; - deletePcode(i+1); - } /* end if */ - else i++; - } /* end else if */ - else i++; - } /* end while */ - - return (nchanges); - -} /* end unaryOptimize */ - -/**********************************************************************/ - -sint16 binaryOptimize(void) -{ - sint16 nchanges = 0; - register sint16 stmp16; - register sint16 i; - - TRACE(stderr, "[binaryOptimize]"); - - /* At least two pcodes are needed to perform the following binary */ - /* operator optimizations */ - - i = 0; - while (i < nops-2) - { - if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB)) - { - if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB)) - { - /* Turn the oPUSHBs into an oPUSHs op (temporarily) */ - - if (pptr[i]->op == oPUSHB) - { - pptr[i]->op = oPUSH; - pptr[i]->arg2 = pptr[i]->arg1; - pptr[i]->arg1 = 0; - } /* end if */ - - if (pptr[i+1]->op == oPUSHB) - { - pptr[i+1]->op = oPUSH; - pptr[i+1]->arg2 = pptr[i+1]->arg1; - pptr[i+1]->arg1 = 0; - } /* end if */ - - switch (pptr[i+2]->op) - { - case oADD : - pptr[i]->arg2 += pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oSUB : - pptr[i]->arg2 -= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oMUL : - pptr[i]->arg2 *= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oDIV : - stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2); - pptr[i]->arg2 = stmp16; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oMOD : - pptr[i]->arg2 %= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oSLL : - pptr[i]->arg2 <<= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oSRL : - pptr[i]->arg2 >>= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oSRA : - stmp16 = (((sint16)pptr[i]->arg2) >> pptr[i+1]->arg2); - pptr[i]->arg2 = (uint16)stmp16; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oOR : - pptr[i]->arg2 |= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oAND : - pptr[i]->arg2 &= pptr[i+1]->arg2; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oEQU : - if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1; - else pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oNEQ : - if ((sint16)pptr[i]->arg2 != (sint16)pptr[i+1]->arg2) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oLT : - if ((sint16)pptr[i]->arg2 < (sint16)pptr[i+1]->arg2) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oGTE : - if ((sint16)pptr[i]->arg2 >= (sint16)pptr[i+1]->arg2) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oGT : - if ((sint16)pptr[i]->arg2 > (sint16)pptr[i+1]->arg2) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - case oLTE : - if ((sint16)pptr[i]->arg2 <= (sint16)pptr[i+1]->arg2) - pptr[i]->arg2 = -1; - else - pptr[i]->arg2 = 0; - deletePcodePair((i+1), (i+2)); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - - /* If the oPUSH instruction is still there, see if we can now */ - /* represent it with an oPUSHB instruction */ - - if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) - { - pptr[i]->op = oPUSHB; - pptr[i]->arg1 = pptr[i]->arg2; - pptr[i]->arg2 = 0; - } /* end if */ - - if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256)) - { - pptr[i+1]->op = oPUSHB; - pptr[i+1]->arg1 = pptr[i+1]->arg2; - pptr[i+1]->arg2 = 0; - } /* end if */ - } /* end if */ - - /* A single (constant) pcode is sufficient to perform the */ - /* following binary operator optimizations */ - - else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) || - (pptr[i+1]->op == oLAS) || (pptr[i+1]->op == oLAC)) - { - /* Turn the oPUSHB into a oPUSH op (temporarily) */ - - if (pptr[i]->op == oPUSHB) - { - pptr[i]->op = oPUSH; - pptr[i]->arg2 = pptr[i]->arg1; - pptr[i]->arg1 = 0; - } /* end if */ - - switch (pptr[i+2]->op) - { - case oADD : - if (pptr[i]->arg2 == 0) - { - deletePcodePair(i, (i+2)); - nchanges++; - } /* end if */ - else if (pptr[i]->arg2 == 1) - { - pptr[i+2]->op = oINC; - deletePcode(i); - nchanges++; - } /* end else if */ - else if (pptr[i]->arg2 == (uint16)-1) - { - pptr[i+2]->op = oDEC; - deletePcode(i); - nchanges++; - } /* end else if */ - else i++; - break; - - case oSUB : - if (pptr[i]->arg2 == 0) - { - pptr[i]->op = oNEG; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oMUL : - stmp16 = 0; - switch (pptr[i]->arg2) - { - case 1 : - deletePcodePair(i, (i+2)); - nchanges++; - break; - case 16384 : stmp16++; - case 8192 : stmp16++; - case 4096 : stmp16++; - case 2048 : stmp16++; - case 1024 : stmp16++; - case 512 : stmp16++; - case 256 : stmp16++; - case 128 : stmp16++; - case 64 : stmp16++; - case 32 : stmp16++; - case 16 : stmp16++; - case 8 : stmp16++; - case 4 : stmp16++; - case 2 : stmp16++; - pptr[i]->op = pptr[i+1]->op; - pptr[i]->arg1 = pptr[i+1]->arg1; - pptr[i]->arg2 = pptr[i+1]->arg2; - pptr[i+1]->op = oPUSH; - pptr[i+1]->arg1 = 0; - pptr[i+1]->arg2 = stmp16; - pptr[i+2]->op = oSLL; - nchanges++; - i++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oOR : - if (pptr[i]->arg2 == 0) - { - deletePcodePair(i, (i+2)); - nchanges++; - } /* end if */ - else i++; - break; - - case oAND : - if (pptr[i]->arg2 == 0xffff) - { - deletePcodePair(i, (i+2)); - nchanges++; - } /* end if */ - else i++; - break; - - case oEQU : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oEQUZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oNEQ : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oNEQZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oLT : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oGTEZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oGTE : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oLTZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oGT : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oLTEZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - case oLTE : - if (pptr[i]->arg2 == 0) - { - pptr[i+2]->op = oGTZ; - deletePcode(i); - nchanges++; - } /* end if */ - else i++; - break; - - default : - i++; - break; - - } /* end switch */ - - /* If the oPUSH instruction is still there, see if we can now */ - /* represent it with an oPUSHB instruction */ - - if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) - { - pptr[i]->op = oPUSHB; - pptr[i]->arg1 = pptr[i]->arg2; - pptr[i]->arg2 = 0; - } /* end if */ - } /* end else if */ - else i++; - } /* end if */ - - /* Misc improvements on binary operators */ - - else if (pptr[i]->op == oNEG) - { - /* Negation followed by add is subtraction */ - - if (pptr[i+1]->op == oADD) - { - pptr[i+1]->op = oSUB; - deletePcode(i); - nchanges++; - } - - /* Negation followed by subtraction is addition */ - - else if (pptr[i]->op == oSUB) - { - pptr[i+1]->op = oADD; - deletePcode(i); - nchanges++; - } - else i++; - } - else i++; - } /* end while */ - - return (nchanges); - -} /* end binaryOptimize */ - -/**********************************************************************/ - +/********************************************************************** + * pcopt.c + * Constant Expression Optimizations + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn16.h" + +#include "paslib.h" +#include "popt.h" +#include "polocal.h" +#include "pcopt.h" + +/**********************************************************************/ + +int16_t unaryOptimize(void) +{ + int16_t nchanges = 0; + register uint16_t temp; + register int16_t i; + + TRACE(stderr, "[unaryOptimize]"); + + /* At least two pcodes are need to perform unary optimizations */ + + i = 0; + while (i < nops-1) + { + /* Check for a constant value being pushed onto the stack */ + + if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB)) + { + /* Turn the oPUSHB into an oPUSH op (temporarily) */ + + if (pptr[i]->op == oPUSHB) + { + pptr[i]->op = oPUSH; + pptr[i]->arg2 = pptr[i]->arg1; + pptr[i]->arg1 = 0; + } /* end if */ + + switch (pptr[i+1]->op) + { + /* Delete unary operators on constants */ + case oNEG : + pptr[i]->arg2 = -(pptr[i]->arg2); + deletePcode(i+1); + nchanges++; + break; + + case oABS : + if (signExtend16(pptr[i]->arg2) < 0) + pptr[i]->arg2 = -signExtend16(pptr[i]->arg2); + deletePcode(i+1); + nchanges++; + break; + + case oINC : + (pptr[i]->arg2)++; + deletePcode(i+1); + nchanges++; + break; + + case oDEC : + (pptr[i]->arg2)--; + deletePcode(i+1); + nchanges++; + break; + + case oNOT : + pptr[i]->arg2 = ~(pptr[i]->arg2); + deletePcode(i+1); + nchanges++; + break; + + /* Simplify binary operations on constants */ + + case oADD : + if (pptr[i]->arg2 == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i+1]->op = oINC; + deletePcode(i); + nchanges++; + } /* end else if */ + else if (pptr[i]->arg2 == (uint16_t)-1) + { + pptr[i+1]->op = oDEC; + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oSUB : + if (pptr[i]->arg2 == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i+1]->op = oDEC; + deletePcode(i); + nchanges++; + } /* end else if */ + else if (pptr[i]->arg2 == (uint16_t)-1) + { + pptr[i+1]->op = oINC; + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oMUL : + case oDIV : + temp = 0; + switch (pptr[i]->arg2) + { + case 1 : + deletePcodePair(i, (i+1)); + nchanges++; + break; + case 16384 : temp++; + case 8192 : temp++; + case 4096 : temp++; + case 2048 : temp++; + case 1024 : temp++; + case 512 : temp++; + case 256 : temp++; + case 128 : temp++; + case 64 : temp++; + case 32 : temp++; + case 16 : temp++; + case 8 : temp++; + case 4 : temp++; + case 2 : temp++; + pptr[i]->arg2 = temp; + if (pptr[i+1]->op == oMUL) + pptr[i+1]->op = oSLL; + else + pptr[i+1]->op = oSRA; + nchanges++; + i++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oSLL : + case oSRL : + case oSRA : + case oOR : + if (pptr[i]->arg2 == 0) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else i++; + break; + + case oAND : + if (pptr[i]->arg2 == 0xffff) + { + deletePcodePair(i, (i+1)); + nchanges++; + } /* end if */ + else i++; + break; + + /* Delete comparisons of constants to zero */ + + case oEQUZ : + if (pptr[i]->arg2 == 0) pptr[i]->arg2 = -1; + else pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + case oNEQZ : + if (pptr[i]->arg2 != 0) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + case oLTZ : + if (signExtend16(pptr[i]->arg2) < 0) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + case oGTEZ : + if (signExtend16(pptr[i]->arg2) >= 0) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + case oGTZ : + if (pptr[i]->arg2 > 0) pptr[i]->arg2 = -1; + else pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + case oLTEZ : + if (pptr[i]->arg2 <= 0) pptr[i]->arg2 = -1; + else pptr[i]->arg2 = 0; + deletePcode(i+1); + nchanges++; + break; + + /* Simplify comparisons with certain constants */ + + case oEQU : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oEQUZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oEQUZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oEQUZ; + nchanges++; + } /* end else if */ + else i++; + break; + + case oNEQ : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oNEQZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oNEQZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oNEQZ; + nchanges++; + } /* end else if */ + else i++; + break; + + case oLT : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oLTZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oLTZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oLTZ; + nchanges++; + } /* end else if */ + else i++; + break; + + case oGTE : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oGTEZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oGTEZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oGTEZ; + nchanges++; + } /* end else if */ + else i++; + break; + + case oGT : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oGTZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oGTZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oGTZ; + nchanges++; + } /* end else if */ + else i++; + break; + + case oLTE : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oLTEZ; + deletePcode(i); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i]->op = oDEC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oLTEZ; + nchanges++; + } /* end else if */ + else if (signExtend16(pptr[i]->arg2) == -1) + { + pptr[i]->op = oINC; + pptr[i]->arg2 = 0; + pptr[i+1]->op = oLTEZ; + nchanges++; + } /* end else if */ + else i++; + break; + + /* Simplify or delete condition branches on constants */ + + case oJEQUZ : + if (pptr[i]->arg2 == 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJNEQZ : + if (pptr[i]->arg2 != 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJLTZ : + if (signExtend16(pptr[i]->arg2) < 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJGTEZ : + if (signExtend16(pptr[i]->arg2) >= 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJGTZ : + if (pptr[i]->arg2 > 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + case oJLTEZ : + if (pptr[i]->arg2 <= 0) + { + pptr[i+1]->op = oJMP; + deletePcode(i); + } /* end if */ + else + deletePcodePair(i, (i+1)); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + + /* If the oPUSH instruction is still there, see if we can now */ + /* represent it with an oPUSHB instruction */ + + if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) + { + pptr[i]->op = oPUSHB; + pptr[i]->arg1 = pptr[i]->arg2; + pptr[i]->arg2 = 0; + } /* end if */ + } /* end if */ + + /* Delete multiple modifications of DSEG pointer */ + + else if (pptr[i]->op == oINDS) + { + if (pptr[i+1]->op == oINDS) + { + pptr[i]->arg2 += pptr[i+1]->arg2; + deletePcode(i+1); + } /* end if */ + else i++; + } /* end else if */ + else i++; + } /* end while */ + + return (nchanges); + +} /* end unaryOptimize */ + +/**********************************************************************/ + +int16_t binaryOptimize(void) +{ + int16_t nchanges = 0; + register int16_t stmp16; + register int16_t i; + + TRACE(stderr, "[binaryOptimize]"); + + /* At least two pcodes are needed to perform the following binary */ + /* operator optimizations */ + + i = 0; + while (i < nops-2) + { + if ((pptr[i]->op == oPUSH) || (pptr[i]->op == oPUSHB)) + { + if ((pptr[i+1]->op == oPUSH) || (pptr[i+1]->op == oPUSHB)) + { + /* Turn the oPUSHBs into an oPUSHs op (temporarily) */ + + if (pptr[i]->op == oPUSHB) + { + pptr[i]->op = oPUSH; + pptr[i]->arg2 = pptr[i]->arg1; + pptr[i]->arg1 = 0; + } /* end if */ + + if (pptr[i+1]->op == oPUSHB) + { + pptr[i+1]->op = oPUSH; + pptr[i+1]->arg2 = pptr[i+1]->arg1; + pptr[i+1]->arg1 = 0; + } /* end if */ + + switch (pptr[i+2]->op) + { + case oADD : + pptr[i]->arg2 += pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSUB : + pptr[i]->arg2 -= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oMUL : + pptr[i]->arg2 *= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oDIV : + stmp16 = pptr[i]->arg2 / signExtend16(pptr[i+1]->arg2); + pptr[i]->arg2 = stmp16; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oMOD : + pptr[i]->arg2 %= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSLL : + pptr[i]->arg2 <<= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSRL : + pptr[i]->arg2 >>= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oSRA : + stmp16 = (((int16_t)pptr[i]->arg2) >> pptr[i+1]->arg2); + pptr[i]->arg2 = (uint16_t)stmp16; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oOR : + pptr[i]->arg2 |= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oAND : + pptr[i]->arg2 &= pptr[i+1]->arg2; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oEQU : + if (pptr[i]->arg2 == pptr[i+1]->arg2) pptr[i]->arg2 = -1; + else pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oNEQ : + if ((int16_t)pptr[i]->arg2 != (int16_t)pptr[i+1]->arg2) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oLT : + if ((int16_t)pptr[i]->arg2 < (int16_t)pptr[i+1]->arg2) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oGTE : + if ((int16_t)pptr[i]->arg2 >= (int16_t)pptr[i+1]->arg2) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oGT : + if ((int16_t)pptr[i]->arg2 > (int16_t)pptr[i+1]->arg2) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + case oLTE : + if ((int16_t)pptr[i]->arg2 <= (int16_t)pptr[i+1]->arg2) + pptr[i]->arg2 = -1; + else + pptr[i]->arg2 = 0; + deletePcodePair((i+1), (i+2)); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + + /* If the oPUSH instruction is still there, see if we can now */ + /* represent it with an oPUSHB instruction */ + + if (pptr[i] && (pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) + { + pptr[i]->op = oPUSHB; + pptr[i]->arg1 = pptr[i]->arg2; + pptr[i]->arg2 = 0; + } /* end if */ + + if (pptr[i+1] && (pptr[i+1]->op == oPUSH) && (pptr[i+1]->arg2 < 256)) + { + pptr[i+1]->op = oPUSHB; + pptr[i+1]->arg1 = pptr[i+1]->arg2; + pptr[i+1]->arg2 = 0; + } /* end if */ + } /* end if */ + + /* A single (constant) pcode is sufficient to perform the */ + /* following binary operator optimizations */ + + else if ((pptr[i+1]->op == oLDSH) || (pptr[i+1]->op == oLDSB) || + (pptr[i+1]->op == oLAS) || (pptr[i+1]->op == oLAC)) + { + /* Turn the oPUSHB into a oPUSH op (temporarily) */ + + if (pptr[i]->op == oPUSHB) + { + pptr[i]->op = oPUSH; + pptr[i]->arg2 = pptr[i]->arg1; + pptr[i]->arg1 = 0; + } /* end if */ + + switch (pptr[i+2]->op) + { + case oADD : + if (pptr[i]->arg2 == 0) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else if (pptr[i]->arg2 == 1) + { + pptr[i+2]->op = oINC; + deletePcode(i); + nchanges++; + } /* end else if */ + else if (pptr[i]->arg2 == (uint16_t)-1) + { + pptr[i+2]->op = oDEC; + deletePcode(i); + nchanges++; + } /* end else if */ + else i++; + break; + + case oSUB : + if (pptr[i]->arg2 == 0) + { + pptr[i]->op = oNEG; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oMUL : + stmp16 = 0; + switch (pptr[i]->arg2) + { + case 1 : + deletePcodePair(i, (i+2)); + nchanges++; + break; + case 16384 : stmp16++; + case 8192 : stmp16++; + case 4096 : stmp16++; + case 2048 : stmp16++; + case 1024 : stmp16++; + case 512 : stmp16++; + case 256 : stmp16++; + case 128 : stmp16++; + case 64 : stmp16++; + case 32 : stmp16++; + case 16 : stmp16++; + case 8 : stmp16++; + case 4 : stmp16++; + case 2 : stmp16++; + pptr[i]->op = pptr[i+1]->op; + pptr[i]->arg1 = pptr[i+1]->arg1; + pptr[i]->arg2 = pptr[i+1]->arg2; + pptr[i+1]->op = oPUSH; + pptr[i+1]->arg1 = 0; + pptr[i+1]->arg2 = stmp16; + pptr[i+2]->op = oSLL; + nchanges++; + i++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oOR : + if (pptr[i]->arg2 == 0) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else i++; + break; + + case oAND : + if (pptr[i]->arg2 == 0xffff) + { + deletePcodePair(i, (i+2)); + nchanges++; + } /* end if */ + else i++; + break; + + case oEQU : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oEQUZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oNEQ : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oNEQZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oLT : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oGTEZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oGTE : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oLTZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oGT : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oLTEZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + case oLTE : + if (pptr[i]->arg2 == 0) + { + pptr[i+2]->op = oGTZ; + deletePcode(i); + nchanges++; + } /* end if */ + else i++; + break; + + default : + i++; + break; + + } /* end switch */ + + /* If the oPUSH instruction is still there, see if we can now */ + /* represent it with an oPUSHB instruction */ + + if ((pptr[i]->op == oPUSH) && (pptr[i]->arg2 < 256)) + { + pptr[i]->op = oPUSHB; + pptr[i]->arg1 = pptr[i]->arg2; + pptr[i]->arg2 = 0; + } /* end if */ + } /* end else if */ + else i++; + } /* end if */ + + /* Misc improvements on binary operators */ + + else if (pptr[i]->op == oNEG) + { + /* Negation followed by add is subtraction */ + + if (pptr[i+1]->op == oADD) + { + pptr[i+1]->op = oSUB; + deletePcode(i); + nchanges++; + } + + /* Negation followed by subtraction is addition */ + + else if (pptr[i]->op == oSUB) + { + pptr[i+1]->op = oADD; + deletePcode(i); + nchanges++; + } + else i++; + } + else i++; + } /* end while */ + + return (nchanges); + +} /* end binaryOptimize */ + +/**********************************************************************/ + diff --git a/misc/pascal/insn16/popt/pcopt.h b/misc/pascal/insn16/popt/pcopt.h index 2a38b481b..02dbae334 100644 --- a/misc/pascal/insn16/popt/pcopt.h +++ b/misc/pascal/insn16/popt/pcopt.h @@ -1,47 +1,53 @@ -/*************************************************************************** - * pcopt.h - * External Declarations associated with PCOPT.C - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ - -#ifndef __PCOPT_H -#define __PCOPT_H - -/*************************************************************************** - * Global Function Prototypes - ***************************************************************************/ - -extern sint16 unaryOptimize ( void ); -extern sint16 binaryOptimize ( void ); - -#endif /* __PCOPT_H */ +/*************************************************************************** + * pcopt.h + * External Declarations associated with PCOPT.C + * + * Copyright (C) 200-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef __PCOPT_H +#define __PCOPT_H + +/*************************************************************************** + * Included Files + ***************************************************************************/ + +#include + +/*************************************************************************** + * Global Function Prototypes + ***************************************************************************/ + +extern int16_t unaryOptimize(void); +extern int16_t binaryOptimize(void); + +#endif /* __PCOPT_H */ diff --git a/misc/pascal/insn16/popt/pfopt.c b/misc/pascal/insn16/popt/pfopt.c index 6e74cc90a..0236b525c 100644 --- a/misc/pascal/insn16/popt/pfopt.c +++ b/misc/pascal/insn16/popt/pfopt.c @@ -2,7 +2,7 @@ * pfopt.c * Finalization of optimized image * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ * Included Files **********************************************************************/ +#include #include #include #include @@ -84,9 +85,9 @@ static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { - OPTYPE op; - uint32 pc; - uint32 opsize; + OPTYPE op; + uint32_t pc; + uint32_t opsize; /* Build label / line number reference table * @@ -105,18 +106,18 @@ static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { opsize = insn_GetOpCode(poffHandle, &op); if (op.op == oLABEL) - { - poffAddToDefinedLabelTable(op.arg2, pc); - } + { + poffAddToDefinedLabelTable(op.arg2, pc); + } else if (op.op == oLINE) - { - poffAddLineNumber(poffHandle, op.arg2, op.arg1, pc); - } + { + poffAddLineNumber(poffHandle, op.arg2, op.arg1, pc); + } else - { - insn_AddTmpOpCode(poffProgHandle, &op); - pc += opsize; - } + { + insn_AddTmpOpCode(poffProgHandle, &op); + pc += opsize; + } } while (op.op != oEND); @@ -130,8 +131,8 @@ static void pass1(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { poffSymHandle_t poffSymHandle; - sint32 symIndex; - sint32 nchanges = 0; + int32_t symIndex; + int32_t nchanges = 0; /* Get a container to temporarily hold any modifications that we * make to the symbol table. @@ -153,49 +154,49 @@ static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) poffLibSymbol_t symbol; symIndex = poffGetSymbol(poffHandle, &symbol); if (symIndex >= 0) - { - if ((symbol.type == STT_PROC) || (symbol.type == STT_FUNC)) - { - /* It is a symbol associated with the program data section. - * Has is value been defined? - */ - - if ((symbol.flags & STF_UNDEFINED) != 0) - { - /* No... Add it to the list of undefined labels */ - - poffAddToUndefinedLabelTable(symbol.value, symIndex); - } - else - { - /* It is a defined symbol. In this case, we should have - * encountered its LABEL marker in the pass1 processing - * and the following look up should not fail. - */ - sint32 value = poffGetPcForDefinedLabel(symbol.value); - if (value < 0) - { - DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value); - fatal(ePOFFCONFUSION); - } - else - { - /* Replace the label value with the section offset - * (pc) value. - */ - - symbol.value = value; - nchanges++; - } - } - } - - /* In either event, we will want to save the symbol in case - * we need to re-write the symbol table. - */ - - (void)poffAddTmpSymbol(poffHandle, poffSymHandle, &symbol); - } + { + if ((symbol.type == STT_PROC) || (symbol.type == STT_FUNC)) + { + /* It is a symbol associated with the program data section. + * Has is value been defined? + */ + + if ((symbol.flags & STF_UNDEFINED) != 0) + { + /* No... Add it to the list of undefined labels */ + + poffAddToUndefinedLabelTable(symbol.value, symIndex); + } + else + { + /* It is a defined symbol. In this case, we should have + * encountered its LABEL marker in the pass1 processing + * and the following look up should not fail. + */ + int32_t value = poffGetPcForDefinedLabel(symbol.value); + if (value < 0) + { + DEBUG(stdout, "Failed to find label L%04lx\n", symbol.value); + fatal(ePOFFCONFUSION); + } + else + { + /* Replace the label value with the section offset + * (pc) value. + */ + + symbol.value = value; + nchanges++; + } + } + } + + /* In either event, we will want to save the symbol in case + * we need to re-write the symbol table. + */ + + (void)poffAddTmpSymbol(poffHandle, poffSymHandle, &symbol); + } } while (symIndex >= 0); @@ -218,9 +219,9 @@ static void pass2(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { - OPTYPE op; - uint32 pc; - uint32 opsize; + OPTYPE op; + uint32_t pc; + uint32_t opsize; /* Read each opcode, generate relocation information and * replace label references with program section offsets. @@ -243,131 +244,131 @@ static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) { opsize = insn_GetOpCode(poffHandle, &op); switch (op.op) - { - /* Load of an address in the rodata section */ - - case oLAC: - /* We are referencing something from the rodata section. - * No special action need be taken. - */ - break; - - /* Call to a procedure or function. */ - - case oPCAL: - { - /* Check if this is a defined label, i.e., a call to - * procedure or function in the same file. - */ - - sint32 value = poffGetPcForDefinedLabel(op.arg2); - if (value >= 0) - { - /* Yes... replace the label reference with - * a text section offset. No relocation record - * is needed in this case. The only relocation - * may be performed is a subsequent program data - * section offset. - */ - - op.arg2 = (uint16)value; - } - else - { - /* Check if this is a undefined label. This would - * occur for a call to a procedure or a function that - * is defined in some other unit file. - */ - - value = poffGetSymIndexForUndefinedLabel(op.arg2); - if (value >= 0) - { - /* Use the value zero now */ - - op.arg2 = 0; - - /* And generate a symbol-based relocation */ - - (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc); - } - else - { - DEBUG(stdout, "Failed to find call label L%04x\n", op.arg2); - fatal(ePOFFCONFUSION); - } - } - } - break; - - /* Jumps to "nearby" addresses */ - - case oJMP: /* Unconditional */ - case oJEQUZ: /* Unary comparisons with zero */ - case oJNEQZ: - case oJLTZ: - case oJGTEZ: - case oJGTZ: - case oJLTEZ: - case oJEQU: /* Binary comparisons */ - case oJNEQ: - case oJLT: - case oJGTE: - case oJGT: - case oJLTE: - { - /* Check if this is a defined label. This must be the case - * because there can be no jumps into a unit file. - */ - - sint32 value = poffGetPcForDefinedLabel(op.arg2); - if (value >= 0) - { - /* Yes... replace the label reference with - * a text section offset. No relocation record - * is needed in this case. The only relocation - * may be performed is a subsequent program data - * sectioin offset. - */ - - op.arg2 = (uint16)value; - } - else - { - DEBUG(stdout, "Failed to find jump label L%04x\n", op.arg2); - fatal(ePOFFCONFUSION); - } - } - break; - - /* References to stack via level offset */ - - case oLAS: /* Load stack address */ - case oLASX: - case oLDS: /* Load value */ - case oLDSH: - case oLDSB: - case oLDSM: - case oSTS: /* Store value */ - case oSTSH: - case oSTSB: - case oSTSM: - case oLDSX: - case oLDSXH: /* Load value indexed */ - case oLDSXB: - case oLDSXM: - case oSTSX: /* Store value indexed */ - case oSTSXH: - case oSTSXB: - case oSTSXM: - { + { + /* Load of an address in the rodata section */ + + case oLAC: + /* We are referencing something from the rodata section. + * No special action need be taken. + */ + break; + + /* Call to a procedure or function. */ + + case oPCAL: + { + /* Check if this is a defined label, i.e., a call to + * procedure or function in the same file. + */ + + int32_t value = poffGetPcForDefinedLabel(op.arg2); + if (value >= 0) + { + /* Yes... replace the label reference with + * a text section offset. No relocation record + * is needed in this case. The only relocation + * may be performed is a subsequent program data + * section offset. + */ + + op.arg2 = (uint16_t)value; + } + else + { + /* Check if this is a undefined label. This would + * occur for a call to a procedure or a function that + * is defined in some other unit file. + */ + + value = poffGetSymIndexForUndefinedLabel(op.arg2); + if (value >= 0) + { + /* Use the value zero now */ + + op.arg2 = 0; + + /* And generate a symbol-based relocation */ + + (void)poffAddRelocation(poffHandle, RLT_PCAL, value, pc); + } + else + { + DEBUG(stdout, "Failed to find call label L%04x\n", op.arg2); + fatal(ePOFFCONFUSION); + } + } + } + break; + + /* Jumps to "nearby" addresses */ + + case oJMP: /* Unconditional */ + case oJEQUZ: /* Unary comparisons with zero */ + case oJNEQZ: + case oJLTZ: + case oJGTEZ: + case oJGTZ: + case oJLTEZ: + case oJEQU: /* Binary comparisons */ + case oJNEQ: + case oJLT: + case oJGTE: + case oJGT: + case oJLTE: + { + /* Check if this is a defined label. This must be the case + * because there can be no jumps into a unit file. + */ + + int32_t value = poffGetPcForDefinedLabel(op.arg2); + if (value >= 0) + { + /* Yes... replace the label reference with + * a text section offset. No relocation record + * is needed in this case. The only relocation + * may be performed is a subsequent program data + * sectioin offset. + */ + + op.arg2 = (uint16_t)value; + } + else + { + DEBUG(stdout, "Failed to find jump label L%04x\n", op.arg2); + fatal(ePOFFCONFUSION); + } + } + break; + + /* References to stack via level offset */ + + case oLAS: /* Load stack address */ + case oLASX: + case oLDS: /* Load value */ + case oLDSH: + case oLDSB: + case oLDSM: + case oSTS: /* Store value */ + case oSTSH: + case oSTSB: + case oSTSM: + case oLDSX: + case oLDSXH: /* Load value indexed */ + case oLDSXB: + case oLDSXM: + case oSTSX: /* Store value indexed */ + case oSTSXH: + case oSTSXB: + case oSTSXM: + { #warning REVISIT - } - break; + } + break; - /* Otherwise, it is not an interesting opcode */ - default: - break; - } + /* Otherwise, it is not an interesting opcode */ + default: + break; + } /* Save the potentially modified opcode in the temporary * program data container. @@ -387,9 +388,9 @@ static void pass3(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) static void pass4(poffHandle_t poffHandle) { - uint32 entryLabel; - sint32 entryOffset; - ubyte fileType; + uint32_t entryLabel; + int32_t entryOffset; + uint8_t fileType; /* What kind of a file did we just process. Was it a program file? * or was it a unit file? @@ -408,9 +409,9 @@ static void pass4(poffHandle_t poffHandle) entryOffset = poffGetPcForDefinedLabel(entryLabel); if (entryOffset < 0) - { - fatal(ePOFFCONFUSION); - } + { + fatal(ePOFFCONFUSION); + } /* Replace file header entry point with the program data * section offset diff --git a/misc/pascal/insn16/popt/pjopt.c b/misc/pascal/insn16/popt/pjopt.c index 4771c72f3..e504a1dce 100644 --- a/misc/pascal/insn16/popt/pjopt.c +++ b/misc/pascal/insn16/popt/pjopt.c @@ -1,449 +1,450 @@ -/********************************************************************** - * pjopt.c - * Branch Optimizations - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include - -#include "keywords.h" -#include "pdefs.h" -#include "pinsn16.h" - -#include "popt.h" -#include "polocal.h" -#include "pjopt.h" - -/**********************************************************************/ - -sint16 BranchOptimize (void) -{ - sint16 nchanges = 0; - register sint16 i; - - TRACE(stderr, "[BranchOptimize]"); - - /* At least two pcodes are need to perform branch optimizations */ - - i = 0; - while (i < nops-1) - { - switch (pptr[i]->op) - { - case oNOT : - switch (pptr[i+1]->op) - { - case oJEQUZ : - pptr[i+1]->op = oJNEQZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJEQUZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oNEG : - switch (pptr[i+1]->op) - { - case oJLTZ : - pptr[i+1]->op = oJGTZ; - deletePcode(i); - nchanges++; - break; - - case oJGTEZ : - pptr[i+1]->op = oJLTEZ; - deletePcode(i); - nchanges++; - break; - - case oJGTZ : - pptr[i+1]->op = oJLTZ; - deletePcode(i); - nchanges++; - break; - - case oJLTEZ : - pptr[i+1]->op = oJGTEZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oEQU : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oNEQ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJNEQ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJEQU; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oNEQ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oEQU; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJEQU; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJNEQ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oLT : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oGTE; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJGTE; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJLT; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oGTE : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oLT; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJLT; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJGTE; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oGT : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oLTE; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJLTE; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJGT; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oLTE : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oGT; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJGT; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJLTE; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oEQUZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oNEQZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJNEQZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJEQUZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oNEQZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oEQUZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - case oJNEQZ : - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oLTZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oGTEZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJGTEZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJLTZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oGTEZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oLTZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJLTZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJGTEZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oGTZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oLTEZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJLTEZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJGTZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - case oLTEZ : - switch (pptr[i+1]->op) - { - case oNOT : - pptr[i]->op = oGTZ; - deletePcode(i+1); - nchanges++; - break; - - case oJEQUZ : - pptr[i+1]->op = oJGTZ; - deletePcode(i); - nchanges++; - break; - - case oJNEQZ : - pptr[i+1]->op = oJLTEZ; - deletePcode(i); - nchanges++; - break; - - default : - i++; - break; - } /* end switch */ - break; - - default : - i++; - break; - } /* end switch */ - } /* end while */ - return (nchanges); - -} /* end BranchOptimize */ - -/**********************************************************************/ - +/********************************************************************** + * pjopt.c + * Branch Optimizations + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn16.h" + +#include "popt.h" +#include "polocal.h" +#include "pjopt.h" + +/**********************************************************************/ + +int16_t BranchOptimize (void) +{ + int16_t nchanges = 0; + register int16_t i; + + TRACE(stderr, "[BranchOptimize]"); + + /* At least two pcodes are need to perform branch optimizations */ + + i = 0; + while (i < nops-1) + { + switch (pptr[i]->op) + { + case oNOT : + switch (pptr[i+1]->op) + { + case oJEQUZ : + pptr[i+1]->op = oJNEQZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJEQUZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oNEG : + switch (pptr[i+1]->op) + { + case oJLTZ : + pptr[i+1]->op = oJGTZ; + deletePcode(i); + nchanges++; + break; + + case oJGTEZ : + pptr[i+1]->op = oJLTEZ; + deletePcode(i); + nchanges++; + break; + + case oJGTZ : + pptr[i+1]->op = oJLTZ; + deletePcode(i); + nchanges++; + break; + + case oJLTEZ : + pptr[i+1]->op = oJGTEZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oEQU : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oNEQ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJNEQ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJEQU; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oNEQ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oEQU; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJEQU; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJNEQ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oLT : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oGTE; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJGTE; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJLT; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oGTE : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oLT; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJLT; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJGTE; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oGT : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oLTE; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJLTE; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJGT; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oLTE : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oGT; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJGT; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJLTE; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oEQUZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oNEQZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJNEQZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJEQUZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oNEQZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oEQUZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + case oJNEQZ : + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oLTZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oGTEZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJGTEZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJLTZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oGTEZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oLTZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJLTZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJGTEZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oGTZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oLTEZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJLTEZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJGTZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + case oLTEZ : + switch (pptr[i+1]->op) + { + case oNOT : + pptr[i]->op = oGTZ; + deletePcode(i+1); + nchanges++; + break; + + case oJEQUZ : + pptr[i+1]->op = oJGTZ; + deletePcode(i); + nchanges++; + break; + + case oJNEQZ : + pptr[i+1]->op = oJLTEZ; + deletePcode(i); + nchanges++; + break; + + default : + i++; + break; + } /* end switch */ + break; + + default : + i++; + break; + } /* end switch */ + } /* end while */ + return (nchanges); + +} /* end BranchOptimize */ + +/**********************************************************************/ + diff --git a/misc/pascal/insn16/popt/pjopt.h b/misc/pascal/insn16/popt/pjopt.h index ccb2e14b0..4c083e0e3 100644 --- a/misc/pascal/insn16/popt/pjopt.h +++ b/misc/pascal/insn16/popt/pjopt.h @@ -1,42 +1,52 @@ -/*************************************************************************** - * pjopt.h - * External Declarations associated with pjopt.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ - -#ifndef __PJOPT_H -#define __PJOPT_H - -sint16 BranchOptimize ( void ); - +/*************************************************************************** + * pjopt.h + * External Declarations associated with pjopt.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef __PJOPT_H +#define __PJOPT_H + +/*************************************************************************** + * Included Files + ***************************************************************************/ + +#include + +/*************************************************************************** + * Public Function Prototypes + ***************************************************************************/ + +int16_t BranchOptimize(void); + #endif /* __PJOPT_H */ \ No newline at end of file diff --git a/misc/pascal/insn16/popt/plopt.c b/misc/pascal/insn16/popt/plopt.c index 906e35976..2f8ff39f0 100644 --- a/misc/pascal/insn16/popt/plopt.c +++ b/misc/pascal/insn16/popt/plopt.c @@ -1,249 +1,250 @@ -/********************************************************************** - * plopt.c - * Load/Store Optimizations - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include - -#include "keywords.h" -#include "pdefs.h" -#include "pinsn16.h" - -#include "popt.h" -#include "polocal.h" -#include "plopt.h" - -/**********************************************************************/ - -sint16 LoadOptimize(void) -{ - uint16 val; - sint16 nchanges = 0; - register sint16 i; - - TRACE(stderr, "[LoadOptimize]"); - - /* At least two pcodes are need to perform Load optimizations */ - - i = 0; - while (i < nops-1) - { - switch (pptr[i]->op) - { - /* Eliminate duplicate loads */ - - case oLDSH : - if ((pptr[i+1]->op == oLDSH) && - (pptr[i+1]->arg1 == pptr[i]->arg1) && - (pptr[i+1]->arg2 == pptr[i]->arg2)) - { - pptr[i+1]->op = oDUPH; - pptr[i+1]->arg1 = 0; - pptr[i+1]->arg2 = 0; - nchanges++; - i += 2; - } /* end if */ - else i++; - break; - - /* Convert loads indexed by a constant to unindexed loads */ - - case oPUSH : - case oPUSHB : - /* Get the index value */ - - if (pptr[i]->op == oPUSH) - { - val = pptr[i]->arg2; - } - else - { - val = pptr[i]->arg1; - } - - /* If the following instruction is a load, add the constant - * index value to the address and switch the opcode to the - * unindexed form. - */ - - if (pptr[i+1]->op == oLDSXH) - { - pptr[i+1]->op = oLDSH; - pptr[i+1]->arg2 += val; - deletePcode (i); - nchanges++; - } /* end if */ - else if (pptr[i+1]->op == oLASX) - { - pptr[i+1]->op = oLAS; - pptr[i+1]->arg2 += val; - deletePcode (i); - nchanges++; - } /* end else if */ - else if (pptr[i+1]->op == oLDSXB) - { - pptr[i+1]->op = oLDSB; - pptr[i+1]->arg2 += val; - deletePcode (i); - nchanges++; - } /* end if */ - else if (pptr[i+1]->op == oLDSXM) - { - pptr[i+1]->op = oLDSM; - pptr[i+1]->arg2 += val; - deletePcode (i); - nchanges++; - } /* end if */ - else if (val < 256) - { - pptr[i]->op = oPUSHB; - pptr[i]->arg1 = val; - pptr[i]->arg2 = 0; - i++; - } /* end else if */ - else i++; - break; - - default : - i++; - break; - } /* end switch */ - } /* end while */ - return (nchanges); -} /* end LoadOptimize */ - -/**********************************************************************/ -sint16 StoreOptimize (void) -{ - uint16 val; - sint16 nchanges = 0; - register sint16 i; - - TRACE(stderr, "[StoreOptimize]"); - - /* At least two pcodes are need to perform the following Store */ - /* optimizations */ - - i = 0; - while (i < nops-1) - { - switch (pptr[i]->op) - { - /* Eliminate store followed by load */ - - case oSTSH : - if ((pptr[i+1]->op == oLDSH) && - (pptr[i+1]->arg1 == pptr[i]->arg1) && - (pptr[i+1]->arg2 == pptr[i]->arg2)) - { - pptr[i+1]->op = oSTSH; - pptr[i]->op = oDUPH; - pptr[i]->arg1 = 0; - pptr[i]->arg2 = 0; - nchanges++; - i += 2; - } /* end if */ - else i++; - break; - - /* Convert stores indexed by a constant to unindexed stores */ - case oPUSH : - /* Get the index value */ - - if (pptr[i]->op == oPUSH) - { - val = pptr[i]->arg2; - } - else - { - val = pptr[i]->arg1; - } - - /* If the following instruction is a store, add the constant - * index value to the address and switch the opcode to the - * unindexed form. - */ - - if (i < nops-2) - { - if (pptr[i+2]->op == oSTSXH) - { - pptr[i+2]->op = oSTSH; - pptr[i+2]->arg2 += pptr[i]->arg2; - deletePcode (i); - nchanges++; - } /* end if */ - else if (pptr[i+2]->op == oSTSXB) - { - pptr[i+2]->op = oSTSB; - pptr[i+2]->arg2 += pptr[i]->arg2; - deletePcode (i); - nchanges++; - } /* end if */ - else i++; - } /* end if */ - else i++; - break; - - case oPUSHB : - if (i < nops-2) - { - if (pptr[i+2]->op == oSTSXB) - { - pptr[i+2]->op = oSTSB; - pptr[i+2]->arg2 += pptr[i]->arg2; - deletePcode (i); - nchanges++; - } /* end if */ - else i++; - } /* end if */ - else i++; - break; - - default : - i++; - break; - } /* end switch */ - } /* end while */ - - return (nchanges); - -} /* end StoreOptimize */ - -/**********************************************************************/ - +/********************************************************************** + * plopt.c + * Load/Store Optimizations + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn16.h" + +#include "popt.h" +#include "polocal.h" +#include "plopt.h" + +/**********************************************************************/ + +int16_t LoadOptimize(void) +{ + uint16_t val; + int16_t nchanges = 0; + register int16_t i; + + TRACE(stderr, "[LoadOptimize]"); + + /* At least two pcodes are need to perform Load optimizations */ + + i = 0; + while (i < nops-1) + { + switch (pptr[i]->op) + { + /* Eliminate duplicate loads */ + + case oLDSH : + if ((pptr[i+1]->op == oLDSH) && + (pptr[i+1]->arg1 == pptr[i]->arg1) && + (pptr[i+1]->arg2 == pptr[i]->arg2)) + { + pptr[i+1]->op = oDUPH; + pptr[i+1]->arg1 = 0; + pptr[i+1]->arg2 = 0; + nchanges++; + i += 2; + } /* end if */ + else i++; + break; + + /* Convert loads indexed by a constant to unindexed loads */ + + case oPUSH : + case oPUSHB : + /* Get the index value */ + + if (pptr[i]->op == oPUSH) + { + val = pptr[i]->arg2; + } + else + { + val = pptr[i]->arg1; + } + + /* If the following instruction is a load, add the constant + * index value to the address and switch the opcode to the + * unindexed form. + */ + + if (pptr[i+1]->op == oLDSXH) + { + pptr[i+1]->op = oLDSH; + pptr[i+1]->arg2 += val; + deletePcode (i); + nchanges++; + } /* end if */ + else if (pptr[i+1]->op == oLASX) + { + pptr[i+1]->op = oLAS; + pptr[i+1]->arg2 += val; + deletePcode (i); + nchanges++; + } /* end else if */ + else if (pptr[i+1]->op == oLDSXB) + { + pptr[i+1]->op = oLDSB; + pptr[i+1]->arg2 += val; + deletePcode (i); + nchanges++; + } /* end if */ + else if (pptr[i+1]->op == oLDSXM) + { + pptr[i+1]->op = oLDSM; + pptr[i+1]->arg2 += val; + deletePcode (i); + nchanges++; + } /* end if */ + else if (val < 256) + { + pptr[i]->op = oPUSHB; + pptr[i]->arg1 = val; + pptr[i]->arg2 = 0; + i++; + } /* end else if */ + else i++; + break; + + default : + i++; + break; + } /* end switch */ + } /* end while */ + return (nchanges); +} /* end LoadOptimize */ + +/**********************************************************************/ +int16_t StoreOptimize (void) +{ + uint16_t val; + int16_t nchanges = 0; + register int16_t i; + + TRACE(stderr, "[StoreOptimize]"); + + /* At least two pcodes are need to perform the following Store */ + /* optimizations */ + + i = 0; + while (i < nops-1) + { + switch (pptr[i]->op) + { + /* Eliminate store followed by load */ + + case oSTSH : + if ((pptr[i+1]->op == oLDSH) && + (pptr[i+1]->arg1 == pptr[i]->arg1) && + (pptr[i+1]->arg2 == pptr[i]->arg2)) + { + pptr[i+1]->op = oSTSH; + pptr[i]->op = oDUPH; + pptr[i]->arg1 = 0; + pptr[i]->arg2 = 0; + nchanges++; + i += 2; + } /* end if */ + else i++; + break; + + /* Convert stores indexed by a constant to unindexed stores */ + case oPUSH : + /* Get the index value */ + + if (pptr[i]->op == oPUSH) + { + val = pptr[i]->arg2; + } + else + { + val = pptr[i]->arg1; + } + + /* If the following instruction is a store, add the constant + * index value to the address and switch the opcode to the + * unindexed form. + */ + + if (i < nops-2) + { + if (pptr[i+2]->op == oSTSXH) + { + pptr[i+2]->op = oSTSH; + pptr[i+2]->arg2 += pptr[i]->arg2; + deletePcode (i); + nchanges++; + } /* end if */ + else if (pptr[i+2]->op == oSTSXB) + { + pptr[i+2]->op = oSTSB; + pptr[i+2]->arg2 += pptr[i]->arg2; + deletePcode (i); + nchanges++; + } /* end if */ + else i++; + } /* end if */ + else i++; + break; + + case oPUSHB : + if (i < nops-2) + { + if (pptr[i+2]->op == oSTSXB) + { + pptr[i+2]->op = oSTSB; + pptr[i+2]->arg2 += pptr[i]->arg2; + deletePcode (i); + nchanges++; + } /* end if */ + else i++; + } /* end if */ + else i++; + break; + + default : + i++; + break; + } /* end switch */ + } /* end while */ + + return (nchanges); + +} /* end StoreOptimize */ + +/**********************************************************************/ + diff --git a/misc/pascal/insn16/popt/plopt.h b/misc/pascal/insn16/popt/plopt.h index b423006a7..eab655930 100644 --- a/misc/pascal/insn16/popt/plopt.h +++ b/misc/pascal/insn16/popt/plopt.h @@ -1,44 +1,54 @@ -/*************************************************************************** - * plopt.h - * External Declarations associated with plopt.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ - -#ifndef __PLOPT_H -#define __PLOPT_H - -extern sint16 LoadOptimize ( void ); -extern sint16 StoreOptimize ( void ); - -#endif __PLOPT_H - +/*************************************************************************** + * plopt.h + * External Declarations associated with plopt.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef __PLOPT_H +#define __PLOPT_H + +/*************************************************************************** + * Included Files + ***************************************************************************/ + +#include + +/*************************************************************************** + * Public Function Prototypes + ***************************************************************************/ + +extern int16_t LoadOptimize ( void ); +extern int16_t StoreOptimize ( void ); + +#endif __PLOPT_H + diff --git a/misc/pascal/insn16/popt/polocal.c b/misc/pascal/insn16/popt/polocal.c index c2b2a5b67..39260b1dd 100644 --- a/misc/pascal/insn16/popt/polocal.c +++ b/misc/pascal/insn16/popt/polocal.c @@ -1,300 +1,301 @@ -/********************************************************************** - * polocal.c - * P-Code Local Optimizer - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include - -#include "keywords.h" -#include "podefs.h" -#include "pinsn16.h" - -#include "pofflib.h" -#include "paslib.h" -#include "pinsn.h" -#include "pcopt.h" -#include "plopt.h" -#include "pjopt.h" -#include "polocal.h" - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -static void initPTable (void); -static void putPCodeFromTable (void); -static void setupPointer (void); - -/********************************************************************** - * Global Variables - **********************************************************************/ - -OPTYPE ptable [WINDOW]; /* Pcode Table */ -OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */ - -sint16 nops = 0; /* No. Valid Pcode Pointers */ -sint16 end_out = 0; /* 1 = oEND pcode has been output */ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -static poffHandle_t myPoffHandle; /* Handle to POFF object */ -static poffProgHandle_t myPoffProgHandle;/* Handle to temporary POFF object */ - -/********************************************************************** - * Global Functions - **********************************************************************/ - -/***********************************************************************/ - -void localOptimization(poffHandle_t poffHandle, - poffProgHandle_t poffProgHandle) -{ - sint16 nchanges; - - TRACE(stderr, "[pass2]"); - - /* Save the handles for use by other, private functions */ - - myPoffHandle = poffHandle; - myPoffProgHandle = poffProgHandle; - - /* Initialization */ - - initPTable(); - - /* Outer loop traverse the file op-code by op-code until the oEND P-Code - * has been output. NOTE: it is assumed throughout that oEND is the - * final P-Code in the program data section. - */ - - while (!(end_out)) - { - /* The inner loop optimizes the buffered P-Codes until no further - * changes can be made. Then the outer loop will advance the buffer - * by one P-Code - */ - - do - { - nchanges = unaryOptimize (); - nchanges += binaryOptimize(); - nchanges += BranchOptimize(); - nchanges += LoadOptimize(); - nchanges += StoreOptimize(); - } while (nchanges); - - putPCodeFromTable(); - } -} - -/***********************************************************************/ - -void deletePcode(sint16 delIndex) -{ - TRACE(stderr, "[deletePcode]"); - - pptr[delIndex]->op = oNOP; - pptr[delIndex]->arg1 = 0; - pptr[delIndex]->arg2 = 0; - setupPointer(); -} - -/**********************************************************************/ - -void deletePcodePair(sint16 delIndex1, sint16 delIndex2) -{ - TRACE(stderr, "[deletePcodePair]"); - - pptr[delIndex1]->op = oNOP; - pptr[delIndex1]->arg1 = 0; - pptr[delIndex1]->arg2 = 0; - pptr[delIndex2]->op = oNOP; - pptr[delIndex2]->arg1 = 0; - pptr[delIndex2]->arg2 = 0; - setupPointer(); -} - -/********************************************************************** - * Private Functions - **********************************************************************/ - -/***********************************************************************/ - -static void putPCodeFromTable(void) -{ - register sint16 i; - - TRACE(stderr, "[putPCodeFromTable]"); - - /* Transfer all buffered P-Codes (except NOPs) to the optimized file */ - do - { - if ((ptable[0].op != oNOP) && !(end_out)) - { - (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op); - - if (ptable[0].op & o8) - (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1); - - if (ptable[0].op & o16) - { - (void)poffAddTmpProgByte(myPoffProgHandle, - (ptable[0].arg2 >> 8)); - (void)poffAddTmpProgByte(myPoffProgHandle, - (ptable[0].arg2 & 0xff)); - } - - end_out =(ptable[0].op == oEND); - } - - /* Move all P-Codes down one slot */ - - for (i = 1; i < WINDOW; i++) - { - ptable[i-1].op = ptable[i].op ; - ptable[i-1].arg1 = ptable[i].arg1; - ptable[i-1].arg2 = ptable[i].arg2; - } - - /* Then fill the end slot with a new P-Code from the input file */ - - insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]); - - } while (ptable[0].op == oNOP); - setupPointer(); -} - -/**********************************************************************/ - -static void setupPointer(void) -{ - register sint16 pindex; - - TRACE(stderr, "[setupPointer]"); - - for (pindex = 0; pindex < WINDOW; pindex++) - pptr[pindex] = (OPTYPE *) NULL; - - nops = 0; - for (pindex = 0; pindex < WINDOW; pindex++) - { - switch (ptable[pindex].op) - { - /* Terminate list when a break from sequential logic is - * encountered - */ - - case oRET : - case oEND : - case oJMP : - case oLABEL : - case oPCAL : - return; - - /* Terminate list when a condition break from sequential logic is - * encountered but include the conditional branch in the list - */ - - case oJEQUZ : - case oJNEQZ : - case oJLTZ : - case oJGTEZ : - case oJGTZ : - case oJLTEZ : - pptr[nops] = &ptable[pindex]; - nops++; - return; - - /* Skip over NOPs and comment class pcodes */ - - case oNOP : - case oLINE : - break; - - /* Include all other pcodes in the optimization list and continue */ - - default : - pptr[nops] = &ptable[pindex]; - nops++; - } - } -} - -/**********************************************************************/ - -static void initPTable(void) -{ - register sint16 i; - - TRACE(stderr, "[intPTable]"); - - /* Skip over leading pcodes. NOTE: assumes executable begins after - * the first oLABEL pcode - */ - - do - { - insn_GetOpCode(myPoffHandle, &ptable[0]); - - (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op); - - if (ptable[0].op & o8) - { - (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1); - } - - if (ptable[0].op & o16) - { - (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 >> 8)); - (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 & 0xff)); - } /* end if */ - } - while ((ptable[0].op != oLABEL) && (ptable[0].op != oEND)); - - /* Fill the pcode window and setup pointers to working section */ - - for (i = 0; i < WINDOW; i++) - { - insn_GetOpCode(myPoffHandle, &ptable[i]); - } - setupPointer(); -} - -/***********************************************************************/ +/********************************************************************** + * polocal.c + * P-Code Local Optimizer + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include + +#include "keywords.h" +#include "podefs.h" +#include "pinsn16.h" + +#include "pofflib.h" +#include "paslib.h" +#include "pinsn.h" +#include "pcopt.h" +#include "plopt.h" +#include "pjopt.h" +#include "polocal.h" + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +static void initPTable (void); +static void putPCodeFromTable (void); +static void setupPointer (void); + +/********************************************************************** + * Global Variables + **********************************************************************/ + +OPTYPE ptable [WINDOW]; /* Pcode Table */ +OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */ + +int16_t nops = 0; /* No. Valid Pcode Pointers */ +int16_t end_out = 0; /* 1 = oEND pcode has been output */ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +static poffHandle_t myPoffHandle; /* Handle to POFF object */ +static poffProgHandle_t myPoffProgHandle;/* Handle to temporary POFF object */ + +/********************************************************************** + * Global Functions + **********************************************************************/ + +/***********************************************************************/ + +void localOptimization(poffHandle_t poffHandle, + poffProgHandle_t poffProgHandle) +{ + int16_t nchanges; + + TRACE(stderr, "[pass2]"); + + /* Save the handles for use by other, private functions */ + + myPoffHandle = poffHandle; + myPoffProgHandle = poffProgHandle; + + /* Initialization */ + + initPTable(); + + /* Outer loop traverse the file op-code by op-code until the oEND P-Code + * has been output. NOTE: it is assumed throughout that oEND is the + * final P-Code in the program data section. + */ + + while (!(end_out)) + { + /* The inner loop optimizes the buffered P-Codes until no further + * changes can be made. Then the outer loop will advance the buffer + * by one P-Code + */ + + do + { + nchanges = unaryOptimize (); + nchanges += binaryOptimize(); + nchanges += BranchOptimize(); + nchanges += LoadOptimize(); + nchanges += StoreOptimize(); + } while (nchanges); + + putPCodeFromTable(); + } +} + +/***********************************************************************/ + +void deletePcode(int16_t delIndex) +{ + TRACE(stderr, "[deletePcode]"); + + pptr[delIndex]->op = oNOP; + pptr[delIndex]->arg1 = 0; + pptr[delIndex]->arg2 = 0; + setupPointer(); +} + +/**********************************************************************/ + +void deletePcodePair(int16_t delIndex1, int16_t delIndex2) +{ + TRACE(stderr, "[deletePcodePair]"); + + pptr[delIndex1]->op = oNOP; + pptr[delIndex1]->arg1 = 0; + pptr[delIndex1]->arg2 = 0; + pptr[delIndex2]->op = oNOP; + pptr[delIndex2]->arg1 = 0; + pptr[delIndex2]->arg2 = 0; + setupPointer(); +} + +/********************************************************************** + * Private Functions + **********************************************************************/ + +/***********************************************************************/ + +static void putPCodeFromTable(void) +{ + register int16_t i; + + TRACE(stderr, "[putPCodeFromTable]"); + + /* Transfer all buffered P-Codes (except NOPs) to the optimized file */ + do + { + if ((ptable[0].op != oNOP) && !(end_out)) + { + (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op); + + if (ptable[0].op & o8) + (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1); + + if (ptable[0].op & o16) + { + (void)poffAddTmpProgByte(myPoffProgHandle, + (ptable[0].arg2 >> 8)); + (void)poffAddTmpProgByte(myPoffProgHandle, + (ptable[0].arg2 & 0xff)); + } + + end_out =(ptable[0].op == oEND); + } + + /* Move all P-Codes down one slot */ + + for (i = 1; i < WINDOW; i++) + { + ptable[i-1].op = ptable[i].op ; + ptable[i-1].arg1 = ptable[i].arg1; + ptable[i-1].arg2 = ptable[i].arg2; + } + + /* Then fill the end slot with a new P-Code from the input file */ + + insn_GetOpCode(myPoffHandle, &ptable[WINDOW-1]); + + } while (ptable[0].op == oNOP); + setupPointer(); +} + +/**********************************************************************/ + +static void setupPointer(void) +{ + register int16_t pindex; + + TRACE(stderr, "[setupPointer]"); + + for (pindex = 0; pindex < WINDOW; pindex++) + pptr[pindex] = (OPTYPE *) NULL; + + nops = 0; + for (pindex = 0; pindex < WINDOW; pindex++) + { + switch (ptable[pindex].op) + { + /* Terminate list when a break from sequential logic is + * encountered + */ + + case oRET : + case oEND : + case oJMP : + case oLABEL : + case oPCAL : + return; + + /* Terminate list when a condition break from sequential logic is + * encountered but include the conditional branch in the list + */ + + case oJEQUZ : + case oJNEQZ : + case oJLTZ : + case oJGTEZ : + case oJGTZ : + case oJLTEZ : + pptr[nops] = &ptable[pindex]; + nops++; + return; + + /* Skip over NOPs and comment class pcodes */ + + case oNOP : + case oLINE : + break; + + /* Include all other pcodes in the optimization list and continue */ + + default : + pptr[nops] = &ptable[pindex]; + nops++; + } + } +} + +/**********************************************************************/ + +static void initPTable(void) +{ + register int16_t i; + + TRACE(stderr, "[intPTable]"); + + /* Skip over leading pcodes. NOTE: assumes executable begins after + * the first oLABEL pcode + */ + + do + { + insn_GetOpCode(myPoffHandle, &ptable[0]); + + (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].op); + + if (ptable[0].op & o8) + { + (void)poffAddTmpProgByte(myPoffProgHandle, ptable[0].arg1); + } + + if (ptable[0].op & o16) + { + (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 >> 8)); + (void)poffAddTmpProgByte(myPoffProgHandle, (ptable[0].arg2 & 0xff)); + } /* end if */ + } + while ((ptable[0].op != oLABEL) && (ptable[0].op != oEND)); + + /* Fill the pcode window and setup pointers to working section */ + + for (i = 0; i < WINDOW; i++) + { + insn_GetOpCode(myPoffHandle, &ptable[i]); + } + setupPointer(); +} + +/***********************************************************************/ diff --git a/misc/pascal/insn16/popt/polocal.h b/misc/pascal/insn16/popt/polocal.h index 4bfb89b24..9e6010dca 100644 --- a/misc/pascal/insn16/popt/polocal.h +++ b/misc/pascal/insn16/popt/polocal.h @@ -1,73 +1,74 @@ -/*************************************************************************** - * polocal.h - * External Declarations associated with polocal.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ - -#ifndef __POLOCAL_H -#define __POLOCAL_H - -/*************************************************************************** -* Included Files -****************************************************************************/ - -#include "keywords.h" -#include "pdefs.h" -#include "pofflib.h" - -/*************************************************************************** -* Definitions -****************************************************************************/ - -#define WINDOW 10 /* size of optimization window */ - -/*************************************************************************** -* Global Function Prototypes -****************************************************************************/ - -extern void localOptimization(poffHandle_t poffHandle, - poffProgHandle_t poffProgHandle); -extern void deletePcode (sint16 delIndex); -extern void deletePcodePair (sint16 delIndex1, sint16 delIndex2); - -/*************************************************************************** - * Global Variables - ****************************************************************************/ - -extern OPTYPE ptable [WINDOW]; /* Pcode Table */ -extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */ - -extern sint16 nops; /* No. Valid Pcode Pointers */ -extern sint16 end_out; /* 1 = oEND pcode has been output */ - -#endif /* __PLOCAL_H */ +/*************************************************************************** + * polocal.h + * External Declarations associated with polocal.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + +#ifndef __POLOCAL_H +#define __POLOCAL_H + +/*************************************************************************** +* Included Files +****************************************************************************/ + +#include +#include "keywords.h" +#include "pdefs.h" +#include "pofflib.h" + +/*************************************************************************** +* Definitions +****************************************************************************/ + +#define WINDOW 10 /* size of optimization window */ + +/*************************************************************************** +* Global Function Prototypes +****************************************************************************/ + +extern void localOptimization(poffHandle_t poffHandle, + poffProgHandle_t poffProgHandle); +extern void deletePcode (int16_t delIndex); +extern void deletePcodePair (int16_t delIndex1, int16_t delIndex2); + +/*************************************************************************** + * Global Variables + ****************************************************************************/ + +extern OPTYPE ptable [WINDOW]; /* Pcode Table */ +extern OPTYPE *pptr [WINDOW]; /* Valid Pcode Pointers */ + +extern int16_t nops; /* No. Valid Pcode Pointers */ +extern int16_t end_out; /* 1 = oEND pcode has been output */ + +#endif /* __PLOCAL_H */ diff --git a/misc/pascal/insn16/popt/popt.c b/misc/pascal/insn16/popt/popt.c index 749710ada..9e8e033dc 100644 --- a/misc/pascal/insn16/popt/popt.c +++ b/misc/pascal/insn16/popt/popt.c @@ -1,288 +1,289 @@ -/********************************************************************** - * popt.c - * P-Code Optimizer Main Logic - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include -#include - -#include "keywords.h" -#include "podefs.h" -#include "paslib.h" -#include "pofflib.h" - -#include "pinsn.h" -#include "popt.h" -#include "psopt.h" -#include "polocal.h" -#include "pfopt.h" - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -static void readPoffFile (const char *filename); -static void pass1 (void); -static void pass2 (void); -static void pass3 (void); -static void writePoffFile (const char *filename); - -/********************************************************************** - * Global Variables - **********************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -static poffHandle_t poffHandle; /* Handle to POFF object */ - -/********************************************************************** - * Global Functions - **********************************************************************/ - -/***********************************************************************/ - -int main(int argc, char *argv[], char *envp[]) -{ - TRACE(stderr, "[main]"); - - /* Check for existence of filename argument */ - - if (argc < 2) - { - printf("Filename Required\n"); - exit (1); - } /* end if */ - - /* Read the POFF file into memory */ - - readPoffFile(argv[1]); - - /* Performs pass1 optimization */ - - pass1(); - - /* Performs pass2 optimization */ - - insn_ResetOpCodeRead(poffHandle); - pass2(); - - /* Create final section offsets and relocation entries */ - - insn_ResetOpCodeRead(poffHandle); - pass3(); - - /* Write the POFF file */ - - writePoffFile(argv[1]); - return 0; - -} /* End main */ - -/********************************************************************** - * Private Functions - **********************************************************************/ - -/***********************************************************************/ - -static void readPoffFile(const char *filename) -{ - char objname [FNAME_SIZE+1]; - FILE *objFile; - uint16 errcode; - - TRACE(stderr, "[readPoffFile]"); - - /* Open the pass1 POFF object file -- Use .o1 extension */ - - (void)extension(filename, "o1", objname, 1); - if (!(objFile = fopen(objname, "rb"))) - { - printf("Error Opening %s\n", objname); - exit(1); - } /* end if */ - - /* Get a handle to a POFF input object */ - - poffHandle = poffCreateHandle(); - if (!poffHandle) - { - printf("Could not get POFF handle\n"); - exit(1); - } /* end if */ - - /* Read the POFF file into memory */ - - errcode = poffReadFile(poffHandle, objFile); - if (errcode != 0) - { - printf("Could not read POFF file, errcode=0x%02x\n", errcode); - exit(1); - } - - /* Close the input file */ - - fclose(objFile); -} /* end pass1 */ - -/***********************************************************************/ - -static void pass1(void) -{ - poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ - - TRACE(stderr, "[pass1]"); - - /* Create a handle to a temporary object to store new POFF program - * data. - */ - - poffProgHandle = poffCreateProgHandle(); - if (!poffProgHandle) - { - printf("Could not get POFF handle\n"); - exit(1); - } /* end if */ - - /* Clean up garbage left from the wasteful string stack logic */ - - stringStackOptimize(poffHandle, poffProgHandle); - - /* Replace the original program data with the new program data */ - - poffReplaceProgData(poffHandle, poffProgHandle); - - /* Release the temporary POFF object */ - - poffDestroyProgHandle(poffProgHandle); -} /* end pass1 */ - -/***********************************************************************/ - -static void pass2(void) -{ - poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ - - TRACE(stderr, "[pass2]"); - - /* Create a handle to a temporary object to store new POFF program - * data. - */ - - poffProgHandle = poffCreateProgHandle(); - if (!poffProgHandle) - { - printf("Could not get POFF handle\n"); - exit(1); - } /* end if */ - - /* Perform Local Optimizatin Initialization */ - - localOptimization(poffHandle, poffProgHandle); - - /* Replace the original program data with the new program data */ - - poffReplaceProgData(poffHandle, poffProgHandle); - - /* Release the temporary POFF object */ - - poffDestroyProgHandle(poffProgHandle); -} /* end pass2 */ - -/***********************************************************************/ - -static void pass3 (void) -{ - poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ - TRACE(stderr, "[pass3]"); - - /* Create a handle to a temporary object to store new POFF program - * data. - */ - - poffProgHandle = poffCreateProgHandle(); - if (!poffProgHandle) - { - printf("Could not get POFF handle\n"); - exit(1); - } /* end if */ - - /* Finalize program section, create relocation and line number - * sections. - */ - - optFinalize(poffHandle, poffProgHandle); - - /* Release the temporary POFF object */ - - poffDestroyProgHandle(poffProgHandle); -} - -/***********************************************************************/ - -static void writePoffFile(const char *filename) -{ - char optname [FNAME_SIZE+1]; - FILE *optFile; - - TRACE(stderr, "[writePoffFile]"); - - /* Open optimized p-code file -- Use .o extension */ - - (void)extension(filename, "o", optname, 1); - if (!(optFile = fopen(optname, "wb"))) - { - printf("Error Opening %s\n", optname); - exit(1); - } /* end if */ - - /* Then write the new POFF file */ - - poffWriteFile(poffHandle, optFile); - - /* Destroy the POFF object */ - - poffDestroyHandle(poffHandle); - - /* Close the files used on writePoffFile */ - - (void)fclose(optFile); -} /* end writePoffFile */ - -/***********************************************************************/ +/********************************************************************** + * popt.c + * P-Code Optimizer Main Logic + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include +#include + +#include "keywords.h" +#include "podefs.h" +#include "paslib.h" +#include "pofflib.h" + +#include "pinsn.h" +#include "popt.h" +#include "psopt.h" +#include "polocal.h" +#include "pfopt.h" + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +static void readPoffFile (const char *filename); +static void pass1 (void); +static void pass2 (void); +static void pass3 (void); +static void writePoffFile (const char *filename); + +/********************************************************************** + * Global Variables + **********************************************************************/ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +static poffHandle_t poffHandle; /* Handle to POFF object */ + +/********************************************************************** + * Global Functions + **********************************************************************/ + +/***********************************************************************/ + +int main(int argc, char *argv[], char *envp[]) +{ + TRACE(stderr, "[main]"); + + /* Check for existence of filename argument */ + + if (argc < 2) + { + printf("Filename Required\n"); + exit (1); + } /* end if */ + + /* Read the POFF file into memory */ + + readPoffFile(argv[1]); + + /* Performs pass1 optimization */ + + pass1(); + + /* Performs pass2 optimization */ + + insn_ResetOpCodeRead(poffHandle); + pass2(); + + /* Create final section offsets and relocation entries */ + + insn_ResetOpCodeRead(poffHandle); + pass3(); + + /* Write the POFF file */ + + writePoffFile(argv[1]); + return 0; + +} /* End main */ + +/********************************************************************** + * Private Functions + **********************************************************************/ + +/***********************************************************************/ + +static void readPoffFile(const char *filename) +{ + char objname [FNAME_SIZE+1]; + FILE *objFile; + uint16_t errcode; + + TRACE(stderr, "[readPoffFile]"); + + /* Open the pass1 POFF object file -- Use .o1 extension */ + + (void)extension(filename, "o1", objname, 1); + if (!(objFile = fopen(objname, "rb"))) + { + printf("Error Opening %s\n", objname); + exit(1); + } /* end if */ + + /* Get a handle to a POFF input object */ + + poffHandle = poffCreateHandle(); + if (!poffHandle) + { + printf("Could not get POFF handle\n"); + exit(1); + } /* end if */ + + /* Read the POFF file into memory */ + + errcode = poffReadFile(poffHandle, objFile); + if (errcode != 0) + { + printf("Could not read POFF file, errcode=0x%02x\n", errcode); + exit(1); + } + + /* Close the input file */ + + fclose(objFile); +} /* end pass1 */ + +/***********************************************************************/ + +static void pass1(void) +{ + poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ + + TRACE(stderr, "[pass1]"); + + /* Create a handle to a temporary object to store new POFF program + * data. + */ + + poffProgHandle = poffCreateProgHandle(); + if (!poffProgHandle) + { + printf("Could not get POFF handle\n"); + exit(1); + } /* end if */ + + /* Clean up garbage left from the wasteful string stack logic */ + + stringStackOptimize(poffHandle, poffProgHandle); + + /* Replace the original program data with the new program data */ + + poffReplaceProgData(poffHandle, poffProgHandle); + + /* Release the temporary POFF object */ + + poffDestroyProgHandle(poffProgHandle); +} /* end pass1 */ + +/***********************************************************************/ + +static void pass2(void) +{ + poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ + + TRACE(stderr, "[pass2]"); + + /* Create a handle to a temporary object to store new POFF program + * data. + */ + + poffProgHandle = poffCreateProgHandle(); + if (!poffProgHandle) + { + printf("Could not get POFF handle\n"); + exit(1); + } /* end if */ + + /* Perform Local Optimizatin Initialization */ + + localOptimization(poffHandle, poffProgHandle); + + /* Replace the original program data with the new program data */ + + poffReplaceProgData(poffHandle, poffProgHandle); + + /* Release the temporary POFF object */ + + poffDestroyProgHandle(poffProgHandle); +} /* end pass2 */ + +/***********************************************************************/ + +static void pass3 (void) +{ + poffProgHandle_t poffProgHandle; /* Handle to temporary POFF object */ + TRACE(stderr, "[pass3]"); + + /* Create a handle to a temporary object to store new POFF program + * data. + */ + + poffProgHandle = poffCreateProgHandle(); + if (!poffProgHandle) + { + printf("Could not get POFF handle\n"); + exit(1); + } /* end if */ + + /* Finalize program section, create relocation and line number + * sections. + */ + + optFinalize(poffHandle, poffProgHandle); + + /* Release the temporary POFF object */ + + poffDestroyProgHandle(poffProgHandle); +} + +/***********************************************************************/ + +static void writePoffFile(const char *filename) +{ + char optname [FNAME_SIZE+1]; + FILE *optFile; + + TRACE(stderr, "[writePoffFile]"); + + /* Open optimized p-code file -- Use .o extension */ + + (void)extension(filename, "o", optname, 1); + if (!(optFile = fopen(optname, "wb"))) + { + printf("Error Opening %s\n", optname); + exit(1); + } /* end if */ + + /* Then write the new POFF file */ + + poffWriteFile(poffHandle, optFile); + + /* Destroy the POFF object */ + + poffDestroyHandle(poffHandle); + + /* Close the files used on writePoffFile */ + + (void)fclose(optFile); +} /* end writePoffFile */ + +/***********************************************************************/ diff --git a/misc/pascal/insn16/popt/psopt.c b/misc/pascal/insn16/popt/psopt.c index 8d36ac0aa..0881204c3 100644 --- a/misc/pascal/insn16/popt/psopt.c +++ b/misc/pascal/insn16/popt/psopt.c @@ -2,7 +2,7 @@ * psopt.c * String Stack Optimizaitons * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ * Included Files **********************************************************************/ +#include #include #include #include @@ -70,10 +71,10 @@ * Private Data **********************************************************************/ -static ubyte *pbuffer[NPBUFFERS]; -static int nbytes_in_pbuffer[NPBUFFERS]; -static int current_level = -1; -static int inch; +static uint8_t *pbuffer[NPBUFFERS]; +static int nbytes_in_pbuffer[NPBUFFERS]; +static int current_level = -1; +static int inch; /********************************************************************** * Private Function Prototypes @@ -97,7 +98,7 @@ static inline void putbuf(int c, poffProgHandle_t poffProgHandle) { /* No PUSHS encountered. Write byte directly to output */ - poffAddTmpProgByte(poffProgHandle, (ubyte)c); + poffAddTmpProgByte(poffProgHandle, (uint8_t)c); } else { @@ -106,7 +107,7 @@ static inline void putbuf(int c, poffProgHandle_t poffProgHandle) */ int idx = nbytes_in_pbuffer[dlvl]; - ubyte *dest = pbuffer[dlvl] + idx; + uint8_t *dest = pbuffer[dlvl] + idx; *dest = c; nbytes_in_pbuffer[dlvl] = idx + 1; } @@ -122,7 +123,7 @@ static inline void flushc(int c, poffProgHandle_t poffProgHandle) int dlvl = current_level - 1; int idx = nbytes_in_pbuffer[dlvl]; - ubyte *dest = pbuffer[dlvl] + idx; + uint8_t *dest = pbuffer[dlvl] + idx; *dest = c; nbytes_in_pbuffer[dlvl] = idx + 1; } @@ -132,45 +133,45 @@ static inline void flushc(int c, poffProgHandle_t poffProgHandle) * buffer */ - poffAddTmpProgByte(poffProgHandle, (ubyte)c); + poffAddTmpProgByte(poffProgHandle, (uint8_t)c); } } static inline void flushbuf(poffProgHandle_t poffProgHandle) { - uint16 errCode; + uint16_t errCode; int slvl = current_level; if (nbytes_in_pbuffer[slvl] > 0) { if (current_level > 0) - { - /* Nested PUSHS encountered. Flush buffer into buffer associated - * with the previous nesting level. - */ - - int dlvl = slvl - 1; - ubyte *src = pbuffer[slvl]; - ubyte *dest = pbuffer[dlvl] + nbytes_in_pbuffer[dlvl]; - - memcpy(dest, src, nbytes_in_pbuffer[slvl]); - nbytes_in_pbuffer[dlvl] += nbytes_in_pbuffer[slvl]; - } + { + /* Nested PUSHS encountered. Flush buffer into buffer associated + * with the previous nesting level. + */ + + int dlvl = slvl - 1; + uint8_t *src = pbuffer[slvl]; + uint8_t *dest = pbuffer[dlvl] + nbytes_in_pbuffer[dlvl]; + + memcpy(dest, src, nbytes_in_pbuffer[slvl]); + nbytes_in_pbuffer[dlvl] += nbytes_in_pbuffer[slvl]; + } else - { - /* Only one PUSHS encountered. Flush directly to the output - * buffer - */ - - errCode = poffWriteTmpProgBytes(pbuffer[0], nbytes_in_pbuffer[0], - poffProgHandle); - - if (errCode != eNOERROR) - { - printf("Error writing to file: %d\n", errCode); - exit(1); - } - } + { + /* Only one PUSHS encountered. Flush directly to the output + * buffer + */ + + errCode = poffWriteTmpProgBytes(pbuffer[0], nbytes_in_pbuffer[0], + poffProgHandle); + + if (errCode != eNOERROR) + { + printf("Error writing to file: %d\n", errCode); + exit(1); + } + } } nbytes_in_pbuffer[slvl] = 0; } @@ -188,49 +189,49 @@ static void dopush(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) /* Search for a PUSHS opcode */ if (inch != oPUSHS) - { - /* Its not PUSHS, just echo to the output file/buffer */ + { + /* Its not PUSHS, just echo to the output file/buffer */ - putbuf(inch, poffProgHandle); + putbuf(inch, poffProgHandle); - /* Get the next byte from the input stream */ + /* Get the next byte from the input stream */ - opcode = inch; - inch = poffGetProgByte(poffHandle); + opcode = inch; + inch = poffGetProgByte(poffHandle); - /* Check for an 8-bit argument */ + /* Check for an 8-bit argument */ - if ((opcode & o8) != 0) - { - /* Echo the 8-bit argument */ + if ((opcode & o8) != 0) + { + /* Echo the 8-bit argument */ - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - } + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + } - /* Check for a 16-bit argument */ + /* Check for a 16-bit argument */ - if ((opcode & o16) != 0) - { - /* Echo the 16-bit argument */ + if ((opcode & o16) != 0) + { + /* Echo the 16-bit argument */ - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - } - } + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + } + } else - { - /* We have found PUSHS. No search for the next occurrence - * of either and instruction that increments the string - * stack or for the matching POPS - */ - - current_level++; - dopop(poffHandle, poffProgHandle); - current_level--; - } + { + /* We have found PUSHS. No search for the next occurrence + * of either and instruction that increments the string + * stack or for the matching POPS + */ + + current_level++; + dopop(poffHandle, poffProgHandle); + current_level--; + } } } @@ -255,88 +256,88 @@ static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) /* Did we encounter another PUSHS? */ if (inch == oPUSHS) - { - /* Yes... recurse to handle it */ + { + /* Yes... recurse to handle it */ - current_level++; - dopop(poffHandle, poffProgHandle); - current_level--; - } + current_level++; + dopop(poffHandle, poffProgHandle); + current_level--; + } else if (inch == oPOPS) - { - /* Flush the buffered data without the PUSHS */ + { + /* Flush the buffered data without the PUSHS */ - flushbuf(poffProgHandle); + flushbuf(poffProgHandle); - /* And discard the matching POPS */ + /* And discard the matching POPS */ - inch = poffGetProgByte(poffHandle); - break; - } + inch = poffGetProgByte(poffHandle); + break; + } else if (inch == oLIB) - { - /* Get the 16-bit argument */ - - putbuf(inch, poffProgHandle); - arg16a = poffGetProgByte(poffHandle); - putbuf(arg16a, poffProgHandle); - arg16b = poffGetProgByte(poffHandle); - putbuf(arg16b, poffProgHandle); - arg16 = (arg16a << 8) | arg16b; - inch = poffGetProgByte(poffHandle); - - /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */ - - if ((arg16 == lbMKSTK) || - (arg16 == lbMKSTKSTR) || - (arg16 == lbMKSTKC)) - { - /* Flush the buffered data with the PUSHS */ - - flushc(oPUSHS, poffProgHandle); - flushbuf(poffProgHandle); - - /* And break out of the loop to search for - * the next PUSHS - */ - - break; - } - } + { + /* Get the 16-bit argument */ + + putbuf(inch, poffProgHandle); + arg16a = poffGetProgByte(poffHandle); + putbuf(arg16a, poffProgHandle); + arg16b = poffGetProgByte(poffHandle); + putbuf(arg16b, poffProgHandle); + arg16 = (arg16a << 8) | arg16b; + inch = poffGetProgByte(poffHandle); + + /* Is it LIB MKSTK? MKSTKSTR? or MKSTKC? */ + + if ((arg16 == lbMKSTK) || + (arg16 == lbMKSTKSTR) || + (arg16 == lbMKSTKC)) + { + /* Flush the buffered data with the PUSHS */ + + flushc(oPUSHS, poffProgHandle); + flushbuf(poffProgHandle); + + /* And break out of the loop to search for + * the next PUSHS + */ + + break; + } + } else - { - /* Something else. Put it in the buffer */ + { + /* Something else. Put it in the buffer */ - putbuf(inch, poffProgHandle); + putbuf(inch, poffProgHandle); - /* Get the next byte from the input stream */ + /* Get the next byte from the input stream */ - opcode = inch; - inch = poffGetProgByte(poffHandle); + opcode = inch; + inch = poffGetProgByte(poffHandle); - /* Check for an 8-bit argument */ + /* Check for an 8-bit argument */ - if ((opcode & o8) != 0) - { - /* Buffer the 8-bit argument */ + if ((opcode & o8) != 0) + { + /* Buffer the 8-bit argument */ - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - } + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + } - /* Check for a 16-bit argument */ + /* Check for a 16-bit argument */ - if ((opcode & o16) != 0) - { - /* Buffer the 16-bit argument */ + if ((opcode & o16) != 0) + { + /* Buffer the 16-bit argument */ - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - putbuf(inch, poffProgHandle); - inch = poffGetProgByte(poffHandle); - } - } + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + putbuf(inch, poffProgHandle); + inch = poffGetProgByte(poffHandle); + } + } } } @@ -345,7 +346,7 @@ static void dopop(poffHandle_t poffHandle, poffProgHandle_t poffProgHandle) **********************************************************************/ void stringStackOptimize(poffHandle_t poffHandle, - poffProgHandle_t poffProgHandle) + poffProgHandle_t poffProgHandle) { int i; @@ -353,12 +354,12 @@ void stringStackOptimize(poffHandle_t poffHandle, for (i = 0; i < NPBUFFERS; i++) { - pbuffer[i] = (ubyte*)malloc(PBUFFER_SIZE); + pbuffer[i] = (uint8_t*)malloc(PBUFFER_SIZE); if (pbuffer[i] == NULL) - { - printf("Failed to allocate pcode buffer\n"); - exit(1); - } + { + printf("Failed to allocate pcode buffer\n"); + exit(1); + } nbytes_in_pbuffer[i] = 0; } diff --git a/misc/pascal/insn16/prun/pdbg.c b/misc/pascal/insn16/prun/pdbg.c index c617359c7..9b7c4f5d2 100644 --- a/misc/pascal/insn16/prun/pdbg.c +++ b/misc/pascal/insn16/prun/pdbg.c @@ -1,746 +1,748 @@ -/********************************************************************** - * pdbg.c - * P-Code Debugger - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - **********************************************************************/ - -/********************************************************************** - * Included Files - **********************************************************************/ - -#include -#include -#include -#include - -#include "keywords.h" -#include "pdefs.h" -#include "podefs.h" -#include "pinsn16.h" -#include "pxdefs.h" -#include "pedefs.h" - -#include "paslib.h" -#include "pinsn.h" -#include "pexec.h" -#include "pdbg.h" - -/********************************************************************** - * Definitions - **********************************************************************/ - -#define TRACE_ARRAY_SIZE 16 -#define MAX_BREAK_POINTS 8 -#define DISPLAY_STACK_SIZE 16 -#define DISPLAY_INST_SIZE 16 - -/********************************************************************** - * Private Type Definitions - **********************************************************************/ - -enum command_e -{ - eCMD_NONE = 0, - eCMD_RESET, - eCMD_RUN, - eCMD_STEP, - eCMD_NEXT, - eCMD_GO, - eCMD_BS, - eCMD_BC, - eCMD_DP, - eCMD_DT, - eCMD_DS, - eCMD_DI, - eCMD_DB, - eCMD_HELP, - eCMD_QUIT -}; - -struct trace_s -{ - addr_t pc; - addr_t sp; - ustack_t tos; -}; -typedef struct trace_s trace_t; - -/********************************************************************** - * Private Constant Data - **********************************************************************/ - -/********************************************************************** - * Private Data - **********************************************************************/ - -static enum command_e g_lastcmd = eCMD_NONE; -static uint32 g_lastvalue; - -/********************************************************************** - * Private Function Prototypes - **********************************************************************/ - -static void pdbg_showcommands(void); -static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32 value); -static sint32 pdbg_readdecimal(char *ptr); -static sint32 pdbg_readhex(char *ptr, sint32 defaultvalue); -static void pdbg_programstatus(struct pexec_s *st); -static addr_t pdbg_printpcode(struct pexec_s *st, addr_t pc, sint16 nitems); -static addr_t pdbg_printstack(struct pexec_s *st, addr_t sp, sint16 nitems); -static void pdbg_printregisters(struct pexec_s *st); -static void pdbg_printtracearray(struct pexec_s *st); -static void pdbg_addbreakpoint(addr_t pc); -static void pdbg_deletebreakpoint(sint16 bpno); -static void pdbg_printbreakpoints(struct pexec_s *st); -static void pdbg_checkbreakpoint(struct pexec_s *st); -static void pdbg_initdebugger(void); -static void pdbg_debugpcode(struct pexec_s *st); - -/********************************************************************** - * Global Variables - **********************************************************************/ - -/********************************************************************** - * Private Variables - **********************************************************************/ - -/* Debugging variables */ - -static trace_t g_tracearray[TRACE_ARRAY_SIZE]; - /* Holds execution histor */ -static uint16 g_tracendx; - /* This is the index into the circular g_tracearray */ -static uint16 g_ntracepoints; - /* This is the number of valid enties in g_tracearray */ -static addr_t g_breakpoint[MAX_BREAK_POINTS]; - /* Contains address associated with all active */ - /* break points. */ -static addr_t g_untilpoint; - /* The 'g_untilpoint' is a temporary breakpoint */ -static uint16 g_nbreakpoints; - /* Number of items in breakPoints[] */ -static addr_t g_displayloc; - /* P-code display location display */ -static boolean g_bstopexecution; - /* TRUE means to stop program execution */ - -/* I/O variables */ - -static char g_inline[LINE_SIZE+1]; - /* Command line buffer */ - -/********************************************************************** - * Public Functions - **********************************************************************/ - -void dbg_run(struct pexec_s *st) -{ - addr_t pc; - int i; - - pdbg_showcommands(); - pdbg_initdebugger(); - pdbg_programstatus(st); - - while (TRUE) - { - printf("CMD: "); - (void) fgets(g_inline, LINE_SIZE, stdin); - switch (toupper(g_inline[0])) - { - case 'R' : - switch (toupper(g_inline[1])) { - case 'E' : /* Reset */ - pdbg_execcommand(st, eCMD_RESET, 0); - break; - case 'U' : /* Run */ - pdbg_execcommand(st, eCMD_RUN, 0); - break; - default : - printf("Unrecognized Command\n"); - pdbg_execcommand(st, eCMD_HELP, 0); - break; - } /* end switch */ - break; - case 'S' : /* Single Step (into) */ - pdbg_execcommand(st, eCMD_STEP, 0); - break; - case 'N' : /* Single Step (over) */ - pdbg_execcommand(st, eCMD_NEXT, 0); - break; - case 'G' : /* Go */ - pdbg_execcommand(st, eCMD_GO, 0); - break; - case 'B' : - switch (toupper(g_inline[1])) { - case 'S' : /* Set Breakpoint */ - pc = pdbg_readhex(&g_inline[2], st->pc); - pdbg_execcommand(st, eCMD_BS, pc); - break; - case 'C' : /* Clear Breakpoint */ - i = pdbg_readdecimal(&g_inline[2]); - pdbg_execcommand(st, eCMD_BC, i); - break; - default : - printf("Unrecognized Command\n"); - pdbg_execcommand(st, eCMD_HELP, 0); - break; - } /* end switch */ - break; - case 'D' : - switch (toupper(g_inline[1])) { - case 'P' : /* Display Program Status */ - pdbg_execcommand(st, eCMD_DP, 0); - break; - case 'T' : /* Display Program Trace */ - pdbg_execcommand(st, eCMD_DT, 0); - break; - case 'S' : /* Display Stack */ - pc = pdbg_readhex(&g_inline[2], st->sp); - pdbg_execcommand(st, eCMD_DS, pc); - break; - case 'I' : /* Display Instructions */ - pc = pdbg_readhex(&g_inline[2], st->pc); - pdbg_execcommand(st, eCMD_DI, pc); - break; - case 'B' : /* Display Breakpoints */ - pdbg_execcommand(st, eCMD_DB, pc); - break; - default : - printf("Unrecognized Command\n"); - pdbg_execcommand(st, eCMD_HELP, 0); - break; - } /* end switch */ - break; - case 'Q' : /* Quit */ - pdbg_execcommand(st, eCMD_QUIT, pc); - break; - case 'H' : /* Help */ - case '?' : - pdbg_execcommand(st, eCMD_HELP, 0); - break; - case '\0' : /* Repeat last command */ - case '\n' : /* Repeat last command */ - pdbg_execcommand(st, g_lastcmd, g_lastvalue); - break; - default : - printf("Unrecognized Command\n"); - pdbg_execcommand(st, eCMD_HELP, 0); - break; - } /* end switch */ - } /* end while */ - -} /* end pdbg_debugpcodeProgram */ - -/********************************************************************** - * Private Functions - **********************************************************************/ -/* Show command characters */ - -static void pdbg_showcommands(void) -{ - printf("Commands:\n"); - printf(" RE[set] - Reset\n"); - printf(" RU[n] - Run\n"); - printf(" S[tep] - Single Step (Into)\n"); - printf(" N[ext] - Single Step (Over)\n"); - printf(" G[o] - Go\n"); - printf(" BS xxxx - Set Breakpoint\n"); - printf(" BC n - Clear Breakpoint\n"); - printf(" DP - Display Program Status\n"); - printf(" DT - Display Program Trace\n"); - printf(" DS [xxxx] - Display Stack\n"); - printf(" DI [xxxx] - Display Instructions\n"); - printf(" DB - Display Breakpoints\n"); - printf(" H or ? - Shows this list\n"); - printf(" Q[uit] - Quit\n"); - -} /* end pdbg_showcommands */ - -/***********************************************************************/ -static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32 value) -{ - /* Save the command to resuse if the user enters nothing */ - - g_lastcmd = cmd; - g_lastvalue = value; - - switch (cmd) - { - case eCMD_NONE: /* Do nothing */ - break; - case eCMD_RESET: /* Reset */ - pexec_reset(st); - pdbg_initdebugger(); - pdbg_programstatus(st); - g_lastcmd = eCMD_NONE; - break; - case eCMD_RUN: /* Run */ - pexec_reset(st); - pdbg_initdebugger(); - pdbg_debugpcode(st); - pdbg_programstatus(st); - break; - case eCMD_STEP: /* Single Step (into)*/ - g_bstopexecution = TRUE; - pdbg_debugpcode(st); - pdbg_programstatus(st); - break; - case eCMD_NEXT: /* Single Step (over) */ - if (st->ispace[st->pc] == oPCAL) - { - g_bstopexecution = FALSE; - g_untilpoint = st->pc + 4; - } - else - { - g_bstopexecution = TRUE; - } - pdbg_debugpcode(st); - g_untilpoint = 0; - pdbg_programstatus(st); - break; - case eCMD_GO: /* Go */ - g_bstopexecution = FALSE; - pdbg_debugpcode(st); - pdbg_programstatus(st); - break; - case eCMD_BS: /* Set Breakpoint */ - if (g_nbreakpoints >= MAX_BREAK_POINTS) - { - printf("Too many breakpoints\n"); - g_lastcmd = eCMD_NONE; - } - else if (value >= st->maxpc) - { - printf("Invalid address for breakpoint\n"); - g_lastcmd = eCMD_NONE; - } - else - { - pdbg_addbreakpoint(value); - pdbg_printbreakpoints(st); - } /* end else */ - break; - case eCMD_BC: /* Clear Breakpoint */ - if ((value >= 1) && (value <= g_nbreakpoints)) - { - pdbg_deletebreakpoint(value); - } - else - { - printf("Invalid breakpoint number\n"); - g_lastcmd = eCMD_NONE; - } - pdbg_printbreakpoints(st); - break; - case eCMD_DP: /* Display Program Status */ - pdbg_programstatus(st); - break; - case eCMD_DT: /* Display Program Trace */ - pdbg_printtracearray(st); - break; - case eCMD_DS: /* Display Stack */ - if (value > st->sp) - { - printf("Invalid stack address\n"); - g_lastcmd = eCMD_NONE; - } - else - { - g_lastvalue = pdbg_printstack(st, value, DISPLAY_STACK_SIZE); - } /* end else */ - break; - case eCMD_DI: /* Display Instructions */ - if (value >= st->maxpc) - { - printf("Invalid instruction address\n"); - g_lastcmd = eCMD_NONE; - } - else - { - g_lastvalue = pdbg_printpcode(st, value, DISPLAY_INST_SIZE); - } /* end else */ - break; - case eCMD_DB: /* Display Breakpoints */ - pdbg_printbreakpoints(st); - break; - case eCMD_QUIT: /* Quit */ - printf("Goodbye\n"); - exit(0); - break; - case eCMD_HELP: /* Help */ - default: /* Internal error */ - pdbg_showcommands(); - g_lastcmd = eCMD_NONE; - break; - } /* end switch */ - -} /* end pdbg_execcommand */ - -/***********************************************************************/ -/* Read a decimal value from the input string */ - -static sint32 pdbg_readdecimal(char *ptr) -{ - sint32 decimal = 0; - - while (!isspace(*ptr)) ptr++; - while (isspace(*ptr)) ptr++; - for (; ((*ptr >= '0') && (*ptr <= '9')); ptr++) - decimal = 10*decimal + (sint32)*ptr - (sint32)'0'; - - return decimal; - -} /* end pdbg_readdecimal */ -/***********************************************************************/ -/* Read a hexadecimal value from the input string */ - -static sint32 pdbg_readhex(char *ptr, sint32 defaultvalue) -{ - char c; - sint32 hex = 0; - boolean found = FALSE; - - while (!isspace(*ptr)) ptr++; - while (isspace(*ptr)) ptr++; - while (TRUE) { - - c = toupper(*ptr); - if ((c >= '0') && (c <= '9')) { - hex = ((hex << 4) | ((sint32)c - (sint32)'0')); - found = TRUE; - } /* end if */ - else if ((c >= 'A') && (c <= 'F')) { - hex = ((hex << 4) | ((sint32)c - (sint32)'A' + 10)); - found = TRUE; - } /* end else if */ - else { - if (found) - return hex; - else - return defaultvalue; - } /* end else */ - ptr++; - - } /* end while */ - -} /* end pdbg_readhex */ - -/***********************************************************************/ -/* Print the disassembled P-Code at PC */ - -static void pdbg_programstatus(struct pexec_s *st) -{ - (void)pdbg_printpcode(st, st->pc, 1); - (void)pdbg_printstack(st, st->sp, 2); - pdbg_printregisters(st); - -} /* end pdbg_programstatus */ - -/***********************************************************************/ -/* Print the disassembled P-Code at PC */ - -static addr_t pdbg_printpcode(struct pexec_s *st, addr_t pc, sint16 nitems) -{ - OPTYPE op; - addr_t opsize; - ubyte *address; - - for (; ((pc < st->maxpc) && (nitems > 0)); nitems--) - { - address = &st->ispace[pc]; - - op.op = *address++; - op.arg1 = 0; - op.arg2 = 0; - opsize = 1; - printf("PC:%04x %02x", pc, op.op); - - if ((op.op & o8) != 0) - { - op.arg1 = *address++; - printf("%02x", op.arg1); - opsize++; - } /* end if */ - else - printf(".."); - - if ((op.op & o16) != 0) - { - op.arg2 = ((*address++) << 8); - op.arg2 |= *address++; - printf("%04x", op.arg2); - opsize += 2; - } /* end if */ - else - printf("...."); - - /* The disassemble it to stdout */ - - printf(" "); - insn_DisassemblePCode(stdout, &op); - - /* Get the address of the next P-Code */ - - pc += opsize; - - } /* end for */ - - return pc; - -} /* end pdbg_printpcode */ - -/***********************************************************************/ -/* Print the stack value at SP */ - -static addr_t pdbg_printstack(struct pexec_s *st, addr_t sp, sint16 nitems) -{ - sint32 isp; - - if ((st->sp < st->stacksize) && (sp <= st->sp)) - { - isp = BTOISTACK(sp); - printf("SP:%04x %04x\n", sp, st->dstack.i[isp]); - - for (isp--, sp -= BPERI, nitems--; - ((isp >= 0) && (nitems > 0)); - isp--, sp -= BPERI, nitems--) - printf(" %04x %04x\n", sp, st->dstack.i[isp] & 0xffff); - } /* end if */ - else - { - printf("SP:%04x BAD\n", sp); - } /* end else */ - - return sp; -} /* end pdbg_printstack */ - -/***********************************************************************/ -/* Print the base register */ - -static void pdbg_printregisters(struct pexec_s *st) -{ - if (st->fp <= st->sp) - printf("FP:%04x ", st->fp); - - printf("CSP:%04x\n", st->csp); - -} /* end pdbg_printregisters */ - -/***********************************************************************/ -/* Print the g_tracearray */ - -static void pdbg_printtracearray(struct pexec_s *st) -{ - int nprinted; - int index; - - index = g_tracendx + TRACE_ARRAY_SIZE - g_ntracepoints; - if (index >= TRACE_ARRAY_SIZE) - index -= TRACE_ARRAY_SIZE; - - for (nprinted = 0; nprinted < g_ntracepoints; nprinted++) { - - printf("SP:%04x %04x ", - g_tracearray[ index ].sp, g_tracearray[ index ].tos); - - /* Print the instruction executed at this traced address */ - (void)pdbg_printpcode(st, g_tracearray[ index ].pc, 1); - - /* Index to the next trace entry */ - if (++index >= TRACE_ARRAY_SIZE) - index = 0; - - } /* end for */ - -} /* end pdbg_printtracearray */ - -/***********************************************************************/ -/* Add a breakpoint to the breakpoint array */ - -static void pdbg_addbreakpoint(addr_t pc) -{ - int i; - - /* Is there room for another breakpoint? */ - - if (g_nbreakpoints < MAX_BREAK_POINTS) - { - /* Yes..Check if the breakpoint already exists */ - - for (i = 0; i < g_nbreakpoints; i++) - { - if (g_breakpoint[i] == pc) - { - /* It is already set. Return without doing anything */ - - return; - } - } - - /* The breakpoint is not already set -- set it */ - - g_breakpoint[g_nbreakpoints++] = pc; - } /* end if */ - -} /* end pdbg_addbreakpoint */ - -/***********************************************************************/ -/* Remove a breakpoint from the breakpoint array */ - -static void pdbg_deletebreakpoint(sint16 bpno) -{ - if ((bpno >= 1) && (bpno <= g_nbreakpoints)) { - - for (; (bpno < g_nbreakpoints); bpno++) - g_breakpoint[bpno-1] = g_breakpoint[bpno]; - - g_nbreakpoints--; - - } /* end if */ - -} /* end pdbg_deletebreakpoint */ - -/***********************************************************************/ -/* Print the breakpoint array */ - -static void pdbg_printbreakpoints(struct pexec_s *st) -{ - int i; - - printf("BP:# Address P-Code\n"); - for (i = 0; i < g_nbreakpoints; i++) - { - printf("BP:%d ", (i+1)); - (void)pdbg_printpcode(st, g_breakpoint[i], 1); - } /* end for */ - -} /* end pdbg_printbreakpoints */ - -/***********************************************************************/ -/* Check if a breakpoint is set at the current value of program counter. - * If so, print the instruction and stop execution. */ - -static void pdbg_checkbreakpoint(struct pexec_s *st) -{ - uint16 bpIndex; - - /* Check for a user breakpoint */ - - for (bpIndex = 0; - ((bpIndex < g_nbreakpoints) && (!g_bstopexecution)); - bpIndex++) - { - if (g_breakpoint[bpIndex] == st->pc) - { - printf("Breakpoint #%d -- Execution Stopped\n", (bpIndex+1)); - g_bstopexecution = TRUE; - return; - } /* end if */ - } /* end for */ - -} /* end pdbg_checkbreakpoint */ - -/***********************************************************************/ -/* Initialize Debugger variables */ - -static void pdbg_initdebugger(void) -{ - g_bstopexecution = FALSE; - g_displayloc = 0; - g_tracendx = 0; - g_ntracepoints = 0; -} - -/***********************************************************************/ -/* This function executes the P-Code program until a stopping condition - * is encountered. */ - -static void pdbg_debugpcode(struct pexec_s *st) -{ - uint16 errno; - - do { - /* Trace the next instruction execution */ - - g_tracearray[g_tracendx].pc = st->pc; - g_tracearray[g_tracendx].sp = st->sp; - if (st->sp < st->stacksize) - g_tracearray[g_tracendx].tos = st->dstack.i[BTOISTACK(st->sp)]; - else - g_tracearray[g_tracendx].tos = 0; - - if (++g_tracendx >= TRACE_ARRAY_SIZE) - g_tracendx = 0; - if (g_ntracepoints < TRACE_ARRAY_SIZE) - g_ntracepoints++; - - /* Execute the instruction */ - - errno = pexec(st); - - /* Check for exceptional stopping conditions */ - - if (errno != eNOERROR) - { - if (errno == eEXIT) - printf("Normal Termination\n"); - else - printf("Runtime error 0x%02x -- Execution Stopped\n", errno); - g_bstopexecution = TRUE; - } /* end if */ - - /* Check for normal stopping conditions */ - - if (!g_bstopexecution) - { - /* Check for attempt to execute code outside of legal range */ - - if (st->pc >= st->maxpc) - g_bstopexecution = TRUE; - - /* Check for a temporary breakpoint */ - - else if ((g_untilpoint > 0) && (g_untilpoint == st->pc)) - g_bstopexecution = TRUE; - - /* Check if there is a breakpoint at the next instruction */ - - else if (g_nbreakpoints > 0) - pdbg_checkbreakpoint(st); - } - - } while (!g_bstopexecution); - -} /* end pdbg_debugpcode */ +/********************************************************************** + * pdbg.c + * P-Code Debugger + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************/ + +/********************************************************************** + * Included Files + **********************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "podefs.h" +#include "pinsn16.h" +#include "pxdefs.h" +#include "pedefs.h" + +#include "paslib.h" +#include "pinsn.h" +#include "pexec.h" +#include "pdbg.h" + +/********************************************************************** + * Pre-processor Definitions + **********************************************************************/ + +#define TRACE_ARRAY_SIZE 16 +#define MAX_BREAK_POINTS 8 +#define DISPLAY_STACK_SIZE 16 +#define DISPLAY_INST_SIZE 16 + +/********************************************************************** + * Private Type Definitions + **********************************************************************/ + +enum command_e +{ + eCMD_NONE = 0, + eCMD_RESET, + eCMD_RUN, + eCMD_STEP, + eCMD_NEXT, + eCMD_GO, + eCMD_BS, + eCMD_BC, + eCMD_DP, + eCMD_DT, + eCMD_DS, + eCMD_DI, + eCMD_DB, + eCMD_HELP, + eCMD_QUIT +}; + +struct trace_s +{ + addr_t pc; + addr_t sp; + ustack_t tos; +}; +typedef struct trace_s trace_t; + +/********************************************************************** + * Private Constant Data + **********************************************************************/ + +/********************************************************************** + * Private Data + **********************************************************************/ + +static enum command_e g_lastcmd = eCMD_NONE; +static uint32_t g_lastvalue; + +/********************************************************************** + * Private Function Prototypes + **********************************************************************/ + +static void pdbg_showcommands(void); +static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value); +static int32_t pdbg_readdecimal(char *ptr); +static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue); +static void pdbg_programstatus(struct pexec_s *st); +static addr_t pdbg_printpcode(struct pexec_s *st, addr_t pc, int16_t nitems); +static addr_t pdbg_printstack(struct pexec_s *st, addr_t sp, int16_t nitems); +static void pdbg_printregisters(struct pexec_s *st); +static void pdbg_printtracearray(struct pexec_s *st); +static void pdbg_addbreakpoint(addr_t pc); +static void pdbg_deletebreakpoint(int16_t bpno); +static void pdbg_printbreakpoints(struct pexec_s *st); +static void pdbg_checkbreakpoint(struct pexec_s *st); +static void pdbg_initdebugger(void); +static void pdbg_debugpcode(struct pexec_s *st); + +/********************************************************************** + * Global Variables + **********************************************************************/ + +/********************************************************************** + * Private Variables + **********************************************************************/ + +/* Debugging variables */ + +static trace_t g_tracearray[TRACE_ARRAY_SIZE]; + /* Holds execution histor */ +static uint16_t g_tracendx; + /* This is the index into the circular g_tracearray */ +static uint16_t g_ntracepoints; + /* This is the number of valid enties in g_tracearray */ +static addr_t g_breakpoint[MAX_BREAK_POINTS]; + /* Contains address associated with all active */ + /* break points. */ +static addr_t g_untilpoint; + /* The 'g_untilpoint' is a temporary breakpoint */ +static uint16_t g_nbreakpoints; + /* Number of items in breakPoints[] */ +static addr_t g_displayloc; + /* P-code display location display */ +static bool g_bstopexecution; + /* true means to stop program execution */ + +/* I/O variables */ + +static char g_inline[LINE_SIZE+1]; + /* Command line buffer */ + +/********************************************************************** + * Public Functions + **********************************************************************/ + +void dbg_run(struct pexec_s *st) +{ + addr_t pc; + int i; + + pdbg_showcommands(); + pdbg_initdebugger(); + pdbg_programstatus(st); + + while (true) + { + printf("CMD: "); + (void) fgets(g_inline, LINE_SIZE, stdin); + switch (toupper(g_inline[0])) + { + case 'R' : + switch (toupper(g_inline[1])) { + case 'E' : /* Reset */ + pdbg_execcommand(st, eCMD_RESET, 0); + break; + case 'U' : /* Run */ + pdbg_execcommand(st, eCMD_RUN, 0); + break; + default : + printf("Unrecognized Command\n"); + pdbg_execcommand(st, eCMD_HELP, 0); + break; + } /* end switch */ + break; + case 'S' : /* Single Step (into) */ + pdbg_execcommand(st, eCMD_STEP, 0); + break; + case 'N' : /* Single Step (over) */ + pdbg_execcommand(st, eCMD_NEXT, 0); + break; + case 'G' : /* Go */ + pdbg_execcommand(st, eCMD_GO, 0); + break; + case 'B' : + switch (toupper(g_inline[1])) { + case 'S' : /* Set Breakpoint */ + pc = pdbg_readhex(&g_inline[2], st->pc); + pdbg_execcommand(st, eCMD_BS, pc); + break; + case 'C' : /* Clear Breakpoint */ + i = pdbg_readdecimal(&g_inline[2]); + pdbg_execcommand(st, eCMD_BC, i); + break; + default : + printf("Unrecognized Command\n"); + pdbg_execcommand(st, eCMD_HELP, 0); + break; + } /* end switch */ + break; + case 'D' : + switch (toupper(g_inline[1])) { + case 'P' : /* Display Program Status */ + pdbg_execcommand(st, eCMD_DP, 0); + break; + case 'T' : /* Display Program Trace */ + pdbg_execcommand(st, eCMD_DT, 0); + break; + case 'S' : /* Display Stack */ + pc = pdbg_readhex(&g_inline[2], st->sp); + pdbg_execcommand(st, eCMD_DS, pc); + break; + case 'I' : /* Display Instructions */ + pc = pdbg_readhex(&g_inline[2], st->pc); + pdbg_execcommand(st, eCMD_DI, pc); + break; + case 'B' : /* Display Breakpoints */ + pdbg_execcommand(st, eCMD_DB, pc); + break; + default : + printf("Unrecognized Command\n"); + pdbg_execcommand(st, eCMD_HELP, 0); + break; + } /* end switch */ + break; + case 'Q' : /* Quit */ + pdbg_execcommand(st, eCMD_QUIT, pc); + break; + case 'H' : /* Help */ + case '?' : + pdbg_execcommand(st, eCMD_HELP, 0); + break; + case '\0' : /* Repeat last command */ + case '\n' : /* Repeat last command */ + pdbg_execcommand(st, g_lastcmd, g_lastvalue); + break; + default : + printf("Unrecognized Command\n"); + pdbg_execcommand(st, eCMD_HELP, 0); + break; + } /* end switch */ + } /* end while */ + +} /* end pdbg_debugpcodeProgram */ + +/********************************************************************** + * Private Functions + **********************************************************************/ +/* Show command characters */ + +static void pdbg_showcommands(void) +{ + printf("Commands:\n"); + printf(" RE[set] - Reset\n"); + printf(" RU[n] - Run\n"); + printf(" S[tep] - Single Step (Into)\n"); + printf(" N[ext] - Single Step (Over)\n"); + printf(" G[o] - Go\n"); + printf(" BS xxxx - Set Breakpoint\n"); + printf(" BC n - Clear Breakpoint\n"); + printf(" DP - Display Program Status\n"); + printf(" DT - Display Program Trace\n"); + printf(" DS [xxxx] - Display Stack\n"); + printf(" DI [xxxx] - Display Instructions\n"); + printf(" DB - Display Breakpoints\n"); + printf(" H or ? - Shows this list\n"); + printf(" Q[uit] - Quit\n"); + +} /* end pdbg_showcommands */ + +/***********************************************************************/ +static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value) +{ + /* Save the command to resuse if the user enters nothing */ + + g_lastcmd = cmd; + g_lastvalue = value; + + switch (cmd) + { + case eCMD_NONE: /* Do nothing */ + break; + case eCMD_RESET: /* Reset */ + pexec_reset(st); + pdbg_initdebugger(); + pdbg_programstatus(st); + g_lastcmd = eCMD_NONE; + break; + case eCMD_RUN: /* Run */ + pexec_reset(st); + pdbg_initdebugger(); + pdbg_debugpcode(st); + pdbg_programstatus(st); + break; + case eCMD_STEP: /* Single Step (into)*/ + g_bstopexecution = true; + pdbg_debugpcode(st); + pdbg_programstatus(st); + break; + case eCMD_NEXT: /* Single Step (over) */ + if (st->ispace[st->pc] == oPCAL) + { + g_bstopexecution = false; + g_untilpoint = st->pc + 4; + } + else + { + g_bstopexecution = true; + } + pdbg_debugpcode(st); + g_untilpoint = 0; + pdbg_programstatus(st); + break; + case eCMD_GO: /* Go */ + g_bstopexecution = false; + pdbg_debugpcode(st); + pdbg_programstatus(st); + break; + case eCMD_BS: /* Set Breakpoint */ + if (g_nbreakpoints >= MAX_BREAK_POINTS) + { + printf("Too many breakpoints\n"); + g_lastcmd = eCMD_NONE; + } + else if (value >= st->maxpc) + { + printf("Invalid address for breakpoint\n"); + g_lastcmd = eCMD_NONE; + } + else + { + pdbg_addbreakpoint(value); + pdbg_printbreakpoints(st); + } /* end else */ + break; + case eCMD_BC: /* Clear Breakpoint */ + if ((value >= 1) && (value <= g_nbreakpoints)) + { + pdbg_deletebreakpoint(value); + } + else + { + printf("Invalid breakpoint number\n"); + g_lastcmd = eCMD_NONE; + } + pdbg_printbreakpoints(st); + break; + case eCMD_DP: /* Display Program Status */ + pdbg_programstatus(st); + break; + case eCMD_DT: /* Display Program Trace */ + pdbg_printtracearray(st); + break; + case eCMD_DS: /* Display Stack */ + if (value > st->sp) + { + printf("Invalid stack address\n"); + g_lastcmd = eCMD_NONE; + } + else + { + g_lastvalue = pdbg_printstack(st, value, DISPLAY_STACK_SIZE); + } /* end else */ + break; + case eCMD_DI: /* Display Instructions */ + if (value >= st->maxpc) + { + printf("Invalid instruction address\n"); + g_lastcmd = eCMD_NONE; + } + else + { + g_lastvalue = pdbg_printpcode(st, value, DISPLAY_INST_SIZE); + } /* end else */ + break; + case eCMD_DB: /* Display Breakpoints */ + pdbg_printbreakpoints(st); + break; + case eCMD_QUIT: /* Quit */ + printf("Goodbye\n"); + exit(0); + break; + case eCMD_HELP: /* Help */ + default: /* Internal error */ + pdbg_showcommands(); + g_lastcmd = eCMD_NONE; + break; + } /* end switch */ + +} /* end pdbg_execcommand */ + +/***********************************************************************/ +/* Read a decimal value from the input string */ + +static int32_t pdbg_readdecimal(char *ptr) +{ + int32_t decimal = 0; + + while (!isspace(*ptr)) ptr++; + while (isspace(*ptr)) ptr++; + for (; ((*ptr >= '0') && (*ptr <= '9')); ptr++) + decimal = 10*decimal + (int32_t)*ptr - (int32_t)'0'; + + return decimal; + +} /* end pdbg_readdecimal */ +/***********************************************************************/ +/* Read a hexadecimal value from the input string */ + +static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue) +{ + char c; + int32_t hex = 0; + bool found = false; + + while (!isspace(*ptr)) ptr++; + while (isspace(*ptr)) ptr++; + while (true) { + + c = toupper(*ptr); + if ((c >= '0') && (c <= '9')) { + hex = ((hex << 4) | ((int32_t)c - (int32_t)'0')); + found = true; + } /* end if */ + else if ((c >= 'A') && (c <= 'F')) { + hex = ((hex << 4) | ((int32_t)c - (int32_t)'A' + 10)); + found = true; + } /* end else if */ + else { + if (found) + return hex; + else + return defaultvalue; + } /* end else */ + ptr++; + + } /* end while */ + +} /* end pdbg_readhex */ + +/***********************************************************************/ +/* Print the disassembled P-Code at PC */ + +static void pdbg_programstatus(struct pexec_s *st) +{ + (void)pdbg_printpcode(st, st->pc, 1); + (void)pdbg_printstack(st, st->sp, 2); + pdbg_printregisters(st); + +} /* end pdbg_programstatus */ + +/***********************************************************************/ +/* Print the disassembled P-Code at PC */ + +static addr_t pdbg_printpcode(struct pexec_s *st, addr_t pc, int16_t nitems) +{ + OPTYPE op; + addr_t opsize; + uint8_t *address; + + for (; ((pc < st->maxpc) && (nitems > 0)); nitems--) + { + address = &st->ispace[pc]; + + op.op = *address++; + op.arg1 = 0; + op.arg2 = 0; + opsize = 1; + printf("PC:%04x %02x", pc, op.op); + + if ((op.op & o8) != 0) + { + op.arg1 = *address++; + printf("%02x", op.arg1); + opsize++; + } /* end if */ + else + printf(".."); + + if ((op.op & o16) != 0) + { + op.arg2 = ((*address++) << 8); + op.arg2 |= *address++; + printf("%04x", op.arg2); + opsize += 2; + } /* end if */ + else + printf("...."); + + /* The disassemble it to stdout */ + + printf(" "); + insn_DisassemblePCode(stdout, &op); + + /* Get the address of the next P-Code */ + + pc += opsize; + + } /* end for */ + + return pc; + +} /* end pdbg_printpcode */ + +/***********************************************************************/ +/* Print the stack value at SP */ + +static addr_t pdbg_printstack(struct pexec_s *st, addr_t sp, int16_t nitems) +{ + int32_t isp; + + if ((st->sp < st->stacksize) && (sp <= st->sp)) + { + isp = BTOISTACK(sp); + printf("SP:%04x %04x\n", sp, st->dstack.i[isp]); + + for (isp--, sp -= BPERI, nitems--; + ((isp >= 0) && (nitems > 0)); + isp--, sp -= BPERI, nitems--) + printf(" %04x %04x\n", sp, st->dstack.i[isp] & 0xffff); + } /* end if */ + else + { + printf("SP:%04x BAD\n", sp); + } /* end else */ + + return sp; +} /* end pdbg_printstack */ + +/***********************************************************************/ +/* Print the base register */ + +static void pdbg_printregisters(struct pexec_s *st) +{ + if (st->fp <= st->sp) + printf("FP:%04x ", st->fp); + + printf("CSP:%04x\n", st->csp); + +} /* end pdbg_printregisters */ + +/***********************************************************************/ +/* Print the g_tracearray */ + +static void pdbg_printtracearray(struct pexec_s *st) +{ + int nprinted; + int index; + + index = g_tracendx + TRACE_ARRAY_SIZE - g_ntracepoints; + if (index >= TRACE_ARRAY_SIZE) + index -= TRACE_ARRAY_SIZE; + + for (nprinted = 0; nprinted < g_ntracepoints; nprinted++) { + + printf("SP:%04x %04x ", + g_tracearray[ index ].sp, g_tracearray[ index ].tos); + + /* Print the instruction executed at this traced address */ + (void)pdbg_printpcode(st, g_tracearray[ index ].pc, 1); + + /* Index to the next trace entry */ + if (++index >= TRACE_ARRAY_SIZE) + index = 0; + + } /* end for */ + +} /* end pdbg_printtracearray */ + +/***********************************************************************/ +/* Add a breakpoint to the breakpoint array */ + +static void pdbg_addbreakpoint(addr_t pc) +{ + int i; + + /* Is there room for another breakpoint? */ + + if (g_nbreakpoints < MAX_BREAK_POINTS) + { + /* Yes..Check if the breakpoint already exists */ + + for (i = 0; i < g_nbreakpoints; i++) + { + if (g_breakpoint[i] == pc) + { + /* It is already set. Return without doing anything */ + + return; + } + } + + /* The breakpoint is not already set -- set it */ + + g_breakpoint[g_nbreakpoints++] = pc; + } /* end if */ + +} /* end pdbg_addbreakpoint */ + +/***********************************************************************/ +/* Remove a breakpoint from the breakpoint array */ + +static void pdbg_deletebreakpoint(int16_t bpno) +{ + if ((bpno >= 1) && (bpno <= g_nbreakpoints)) { + + for (; (bpno < g_nbreakpoints); bpno++) + g_breakpoint[bpno-1] = g_breakpoint[bpno]; + + g_nbreakpoints--; + + } /* end if */ + +} /* end pdbg_deletebreakpoint */ + +/***********************************************************************/ +/* Print the breakpoint array */ + +static void pdbg_printbreakpoints(struct pexec_s *st) +{ + int i; + + printf("BP:# Address P-Code\n"); + for (i = 0; i < g_nbreakpoints; i++) + { + printf("BP:%d ", (i+1)); + (void)pdbg_printpcode(st, g_breakpoint[i], 1); + } /* end for */ + +} /* end pdbg_printbreakpoints */ + +/***********************************************************************/ +/* Check if a breakpoint is set at the current value of program counter. + * If so, print the instruction and stop execution. */ + +static void pdbg_checkbreakpoint(struct pexec_s *st) +{ + uint16_t bpIndex; + + /* Check for a user breakpoint */ + + for (bpIndex = 0; + ((bpIndex < g_nbreakpoints) && (!g_bstopexecution)); + bpIndex++) + { + if (g_breakpoint[bpIndex] == st->pc) + { + printf("Breakpoint #%d -- Execution Stopped\n", (bpIndex+1)); + g_bstopexecution = true; + return; + } /* end if */ + } /* end for */ + +} /* end pdbg_checkbreakpoint */ + +/***********************************************************************/ +/* Initialize Debugger variables */ + +static void pdbg_initdebugger(void) +{ + g_bstopexecution = false; + g_displayloc = 0; + g_tracendx = 0; + g_ntracepoints = 0; +} + +/***********************************************************************/ +/* This function executes the P-Code program until a stopping condition + * is encountered. */ + +static void pdbg_debugpcode(struct pexec_s *st) +{ + uint16_t errno; + + do { + /* Trace the next instruction execution */ + + g_tracearray[g_tracendx].pc = st->pc; + g_tracearray[g_tracendx].sp = st->sp; + if (st->sp < st->stacksize) + g_tracearray[g_tracendx].tos = st->dstack.i[BTOISTACK(st->sp)]; + else + g_tracearray[g_tracendx].tos = 0; + + if (++g_tracendx >= TRACE_ARRAY_SIZE) + g_tracendx = 0; + if (g_ntracepoints < TRACE_ARRAY_SIZE) + g_ntracepoints++; + + /* Execute the instruction */ + + errno = pexec(st); + + /* Check for exceptional stopping conditions */ + + if (errno != eNOERROR) + { + if (errno == eEXIT) + printf("Normal Termination\n"); + else + printf("Runtime error 0x%02x -- Execution Stopped\n", errno); + g_bstopexecution = true; + } /* end if */ + + /* Check for normal stopping conditions */ + + if (!g_bstopexecution) + { + /* Check for attempt to execute code outside of legal range */ + + if (st->pc >= st->maxpc) + g_bstopexecution = true; + + /* Check for a temporary breakpoint */ + + else if ((g_untilpoint > 0) && (g_untilpoint == st->pc)) + g_bstopexecution = true; + + /* Check if there is a breakpoint at the next instruction */ + + else if (g_nbreakpoints > 0) + pdbg_checkbreakpoint(st); + } + + } while (!g_bstopexecution); + +} /* end pdbg_debugpcode */ diff --git a/misc/pascal/insn16/prun/pexec.c b/misc/pascal/insn16/prun/pexec.c index 10204ae3c..d73a22077 100644 --- a/misc/pascal/insn16/prun/pexec.c +++ b/misc/pascal/insn16/prun/pexec.c @@ -1,2373 +1,2375 @@ -/**************************************************************************** - * pexec.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include -#include - -#include "keywords.h" -#include "pdefs.h" -#include "pinsn16.h" -#include "pfdefs.h" -#include "pxdefs.h" -#include "pedefs.h" - -#include "paslib.h" -#include "pexec.h" - -#ifdef CONFIG_HAVE_LIBM -#include -#endif - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -#define PTRUE ((ustack_t)-1) -#define PFALSE ((ustack_t) 0) - -/**************************************************************************** - * Macros - ****************************************************************************/ - -/* Remove the value from the top of the stack */ - -#define POP(st, dest) \ - do { \ - dest = (st)->dstack.i[BTOISTACK((st)->sp)]; \ - (st)->sp -= BPERI; \ - } while (0) - -/* Add the value to top of the stack */ - -#define PUSH(st, src) \ - do { \ - (st)->sp += BPERI; \ - (st)->dstack.i[BTOISTACK((st)->sp)] = src; \ - } while (0) - -/* Return an rvalue for the (word) offset from the top of the stack */ - -#define TOS(st, off) \ - (st)->dstack.i[BTOISTACK((st)->sp)-(off)] - -/* Save the src (word) at the dest (word) stack position */ - -#define PUTSTACK(st, src, dest) \ - do { \ - (st)->dstack.i[BTOISTACK(dest)] = src; \ - } while (0) - -/* Return an rvalue for the (word) from the absolute stack position */ - -#define GETSTACK(st, src) \ - (st)->dstack.i[BTOISTACK(src)] - -/* Store a byte to an absolute (byte) stack position */ - -#define PUTBSTACK(st, src,dest) \ - do { \ - (st)->dstack.b[dest] = dest; \ - } while (0) - -/* Return an rvalue for the absolute (byte) stack position */ - -#define GETBSTACK(st, src) \ - (st)->dstack.b[src] - -/* Return the address for an absolute (byte) stack position. */ - -#define ATSTACK(st, src) \ - &(st)->dstack.b[src] - -/* Discard n words from the top of the stack */ - -#define DISCARD(st, n) \ - do { \ - (st)->sp -= BPERI*(n); \ - } while (0) - -/* Release a C string */ - -#define free_cstring(a) \ - free(a) - -/**************************************************************************** - * Private Type Definitions - ****************************************************************************/ - -union fparg_u -{ - float64 f; - uint16 hw[4]; -}; - -typedef union fparg_u fparg_t; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static uint16 pexec_sysio(struct pexec_s *st, ubyte fileno, uint16 subfunc); -static uint16 pexec_libcall(struct pexec_s *st, uint16 subfunc); -static uint16 pexec_execfp(struct pexec_s *st, ubyte fpop); -static void pexec_getfparguments(struct pexec_s *st, ubyte fpop, fparg_t *arg1, fparg_t *arg2); -static ustack_t pexec_readinteger(ubyte *ioptr); -static void pexec_readreal(uint16 *dest, ubyte *ioptr); -static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset); -static ubyte *pexec_mkcstring(ubyte *buffer, int buflen); - -/**************************************************************************** - * Private Variables - ****************************************************************************/ - -static ubyte ioline[LINE_SIZE+1]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pexec_sysio - * - * Description: - * This function process a system I/O operation. - * - ****************************************************************************/ - -static uint16 pexec_sysio(struct pexec_s *st, ubyte fileno, uint16 subfunc) -{ - ustack_t uparm1; - fparg_t fp; - - ubyte *ptr; - - switch (subfunc) - { - case xEOF : -/* FINISH ME -- > */ - break; - case xEOLN : -/* FINISH ME -- > */ - break; - case xRESET : -/* FINISH ME -- > */ - break; - case xREWRITE : -/* FINISH ME -- > */ - break; - - case xREADLN : -/* FINISH ME -- > */ - break; - case xREAD_BINARY : -/* FINISH ME -- > */ - break; - - /* xREAD_INT: - * STACK INPUTS: TOS(st, 0) = address to store integer */ - case xREAD_INT : - (void)fgets((char*)ioline, LINE_SIZE, stdin); - PUTSTACK(st, pexec_readinteger(ioline),TOS(st, 0)); - break; - - /* xREAD_CHAR: - * STACK INPUTS: TOS(st, 0) = address to store integer */ - - case xREAD_CHAR: - (void)fgets((char*)ioline, LINE_SIZE, stdin); - PUTBSTACK(st, ioline[0],TOS(st, 0)); - break; - - /* XREAD_STRING: - - * STACK INPUTS: - * TOS = Number of bytes to read - * TOS-1 = Address to store byte(s) */ - case xREAD_STRING : - (void)fgets((char*)ATSTACK(st, TOS(st, 1)), TOS(st, 0), stdin); - break; - - /* xREAD_REAL: - * STACK INPUTS: TOS = address to store REAL */ - - case xREAD_REAL : - (void)fgets((char*)ioline, LINE_SIZE, stdin); - pexec_readreal((uint16*)ATSTACK(st, TOS(st, 0)), ioline); - break; - - case xWRITELN : - putchar('\n'); - break; - case xWRITE_PAGE : - putchar('\f'); - break; - case xWRITE_BINARY : -/* FINISH ME -- > */ - break; - - /* xWRITE_INT: - * STACK INPUTS: TOS = integer value to write. */ - - case xWRITE_INT : - printf("%ld", signExtend16(TOS(st, 0))); - break; - - /* xWRITE_CHAR: - * STACK INPUTS: TOS = char value to write. */ - - case xWRITE_CHAR : - putchar(TOS(st, 0)); - break; - - /* xWRITE_STRING: - * STACK INPUTS: - * TOS = Number of bytes to write - * TOS-1 = Address of src data */ - - case xWRITE_STRING : - uparm1 = TOS(st, 0); - for (ptr = (ubyte*)ATSTACK(st, TOS(st, 1)); uparm1; uparm1--, ptr++) - putchar(*ptr); - break; - - /* xWRITE_REAL: - * STACK INPUTS: TOS = value of float64 */ - - case xWRITE_REAL : - fp.hw[0] = TOS(st, 3); - fp.hw[1] = TOS(st, 2); - fp.hw[2] = TOS(st, 1); - fp.hw[3] = TOS(st, 0);; - printf("%f", fp.f); - break; - - default : - return eBADSYSIOFUNC; - - } - - return eNOERROR; - -} /* end pexec_sysio */ - -/**************************************************************************** - * Name: pexec_libcall - * - * Description: - * This function process a system I/O operation - * - ****************************************************************************/ - -static uint16 pexec_libcall(struct pexec_s *st, uint16 subfunc) -{ - ustack_t uparm1; - ustack_t uparm2; - addr_t addr1; - addr_t addr2; - uint16 *tmp; - uint16 *ref; - ubyte *src; - ubyte *dest; - ubyte *name; - int len; - sint32 value; - - switch (subfunc) - { - /* Get the value of an environment string - * - * ON INPUT: - * TOS(st, 0) = Number of bytes in environment identifier string - * TOS(st, 1) = Address environment identifier string - * ON RETURN (above replaced with): - * TOS(st, 0) = MS 16-bits of 32-bit C string pointer - * TOS(st, 1) = LS 16-bits of 32-bit C string pointer - */ - - case lbGETENV : - len = TOS(st, 0); /* Number of bytes in string */ - src = (ubyte*)&GETSTACK(st, TOS(st, 1)); /* Pointer to string */ - - /* Make a C string out of the pascal string */ - - name = pexec_mkcstring(src, len); - if (name == NULL) - { - return eNOMEMORY; - } - - /* Make the C-library call and free the string copy */ - - src = (ubyte*)getenv((char*)name); - free_cstring(name); - - /* Save the returned pointer in the stack */ - - TOS(st, 0) = (ustack_t)((uint32)src >> 16); - TOS(st, 1) = (ustack_t)((uint32)src & 0x0000ffff); - break; - - /* Copy pascal string to a pascal string - * - * ON INPUT: - * TOS(st, 0) = address of dest string hdr - * TOS(st, 1) = length of source string - * TOS(st, 2) = pointer to source string - * ON RETURN (input consumed): - */ - - case lbSTR2STR : - /* "Pop" in the input parameters from the stack */ - - POP(st, addr1); /* addr of dest string header */ - POP(st, uparm1); /* length of source data */ - POP(st, addr2); /* addr of source string data */ - - /* Do nothing if the source and destinations are the same - * string. This happens normally on cases like: - * string name; - * char c; - * name := name + c; - */ - - if (addr1 != addr2) - { - /* The source and destination strings are different. - * Make sure that the string length will fit into the destination. - */ - - if (uparm1 >= sSTRING_MAX_SIZE) - { - /* Clip to the maximum size */ - - uparm1 = sSTRING_MAX_SIZE; - len = sSTRING_MAX_SIZE; - } - else - { - /* We have space */ - - len = (int)uparm1; - } - - /* Get proper string pointers */ - - dest = ATSTACK(st, addr1); - src = ATSTACK(st, addr2); - - /* Transfer the (16-bit) string length (must be aligned!) */ - - tmp = (uint16*)dest; - *tmp++ = uparm1; - dest = (ubyte*)tmp; - - /* Then transfer the string contents */ - - memcpy(dest, src, len); - } - break; - - /* Copy C string to a pascal string - * - * ON INPUT: - * TOS(st, 0) = address of dest hdr - * TOS(st, 1) = MS 16-bits of 32-bit C string pointer - * TOS(st, 2) = LS 16-bits of 32-bit C string pointer - * ON RETURN (input consumed): - */ - case lbCSTR2STR : - /* "Pop" in the input parameters from the stack */ - - POP(st, addr1); /* addr of dest string header */ - POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */ - POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */ - - /* Get proper string pointers */ - - dest = ATSTACK(st, addr1); - src = (ubyte*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2); - - /* Handle null src pointer */ - - if (src == NULL) - { - *dest = 0; - } - else - { - /* Get the length of the string */ - - uparm1 = strlen((char*)src); - - /* Make sure that the string length will fit into the - * destination. */ - - if (uparm1 >= sSTRING_MAX_SIZE) - { - /* Clip to the maximum size */ - - uparm1 = sSTRING_MAX_SIZE; - len = sSTRING_MAX_SIZE; - } - else - { - /* We have space */ - - len = (int)uparm1; - } - - /* Transfer the (16-bit) string length (must be aligned!) */ - - tmp = (uint16*)dest; - *tmp++ = uparm1; - dest = (ubyte*)tmp; - - /* Then transfer the string contents */ - - memcpy(dest, src, len); - } - break; - - /* Copy pascal string to a pascal string reference - * procedure str2rstr(src : string; var dest : rstring) - * ON INPUT: - * TOS(st, 0)=address of dest string reference - * TOS(st, 1)=length of source string - * TOS(st, 2)=pointer to source string - * ON RETURN: actual parameters released. - */ - - case lbSTR2RSTR : - /* "Pop" in the input parameters from the stack */ - - POP(st, addr1); /* addr of dest string reference */ - POP(st, uparm1); /* length of source data */ - POP(st, addr2); /* addr of source string data */ - - /* Make sure that the string length will fit into the destination. */ - - if (uparm1 >= sSTRING_MAX_SIZE) - { - return eSTRSTKOVERFLOW; - } - - /* Get a pointer to the destination reference */ - - ref = (uint16*)ATSTACK(st, addr1); - - /* Get proper string pointers */ - - dest = ATSTACK(st, ref[0] - 2); - src = ATSTACK(st, addr2); - - /* Transfer the (16-bit) string length (must be aligned!) */ - - tmp = (uint16*)dest; - *tmp++ = uparm1; - dest = (ubyte*)tmp; - - /* Then transfer the string contents and save the new size */ - - memcpy(dest, src, uparm1); - ref[1] = uparm1; - break; - - /* Copy C string to a pascal string reference - * procedure cstr2str(src : cstring; var dest : string) - * ON INPUT: - * TOS(st, 0)=address of dest string reference - * TOS(st, 0)=MS 16-bits of 32-bit C source string pointer - * TOS(st, 1)=LS 16-bits of 32-bit C source string pointer - * ON RETURN: actual parameters released - */ - - case lbCSTR2RSTR : - /* "Pop" in the input parameters from the stack */ - - POP(st, addr1); /* addr of dest string reference */ - POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */ - POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */ - - /* Get a pointer to the destination reference */ - - ref = (uint16*)ATSTACK(st, addr1); - - /* Get proper string pointers */ - - dest = ATSTACK(st, ref[0] - 2); - src = (ubyte*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2); - - /* Handle null src pointer */ - - if (src == NULL) - { - *dest = 0; - } - else - { - /* Get the length of the string */ - - uparm1 = strlen((char*)src); - - /* Make sure that the string length will fit into the - * destination. */ - - if (uparm1 >= sSTRING_MAX_SIZE) - { - return eSTRSTKOVERFLOW; - } - - /* Transfer the (16-bit) string length (must be aligned!) */ - - tmp = (uint16*)dest; - *tmp++ = uparm1; - dest = (ubyte*)tmp; - - /* Then transfer the string contents */ - - memcpy(dest, src, uparm1); - ref[1] = uparm1; - } - break; - - /* Convert a string to a numeric value - * procedure val(const s : string; var v; var code : word); - * - * Description: - * val() converts the value represented in the string S to a numerical - * value, and stores this value in the variable V, which can be of type - * Longint, Real and Byte. If the conversion isn't succesfull, then the - * parameter Code contains the index of the character in S which - * prevented the conversion. The string S is allowed to contain spaces - * in the beginning. - * - * The string S can contain a number in decimal, hexadecimal, binary or - * octal format, as described in the language reference. - * - * Errors: - * If the conversion doesn¡Çt succeed, the value of Code indicates the - * position where the conversion went wrong. - * - * ON INPUT - * TOS(st, 0)=address of code - * TOS(st, 1)=address of value - * TOS(st, 2)=length of source string - * TOS(st, 3)=pointer to source string - * ON RETURN: actual parameters released - */ - - case lbVAL : - /* Get the string information */ - - len = TOS(st, 2); /* Number of bytes in string */ - src = (ubyte*)&GETSTACK(st, TOS(st, 3)); /* Pointer to string */ - - /* Make a C string out of the pascal string */ - - name = pexec_mkcstring(src, len); - if (name == NULL) - { - return eNOMEMORY; - } - - /* Convert the string to an integer */ - - value = atoi((char*)name); - if ((value < MININT) || (value > MAXINT)) - { - return eINTEGEROVERFLOW; - } - PUTSTACK(st, TOS(st, 0), 0); - PUTSTACK(st, TOS(st, 1), value); - DISCARD(st, 4); - break; - - /* Create an empty string - * function mkstk : string; - * ON INPUT - * ON RETURN - * TOS(st, 0)=length of new string - * TOS(st, 1)=pointer to new string - */ - - case lbMKSTK : - /* Allocate space on the string stack for the new string - * FIXME: This logic does not handle strings with other than the - * default size! - */ - - addr1 = ((st->csp + 1) & ~1); - st->csp += sSTRING_SIZE; /* Allocate max size */ - - /* Save the length at the beginning of the copy */ - - tmp = (uint16*)&GETSTACK(st, addr1); /* Pointer to new string */ - *tmp++ = 0; /* Save current size */ - - /* Update the stack content */ - - PUSH(st, addr1 + sSTRING_HDR_SIZE); /* Pointer to new string */ - PUSH(st, 0); /* Current size */ - break; - - /* Replace a string with a duplicate string residing in allocated - * string stack. - * function mkstkstr(name : string) : string; - * ON INPUT - * TOS(st, 0)=length of original string - * TOS(st, 1)=pointer to original string data - * ON RETURN - * TOS(st, 0)=length of new string (unchanged) - * TOS(st, 1)=pointer to new string data - */ - - case lbMKSTKSTR : - /* Get the parameters from the stack (leaving the string reference - * in place. - */ - - uparm1 = TOS(st, 0); /* Original string size */ - addr1 = TOS(st, 1); /* Original string data pointer */ - - /* Check if there is space on the string stack for the new string - * FIXME: This logic does not handle strings with other than the - * default size! - */ - - if (st->csp + sSTRING_SIZE >= st->spb) - { - return eSTRSTKOVERFLOW; - } - - /* Allocate space on the string stack for the new string */ - - addr2 = ((st->csp + 1) & ~1); - st->csp += sSTRING_SIZE; /* Allocate max size */ - - /* Save the length at the beginning of the copy */ - - tmp = (uint16*)&GETSTACK(st, addr2); /* Pointer to new string */ - *tmp++ = uparm1; /* Save current size */ - dest = (ubyte*)tmp; /* Pointer to string data */ - - /* Copy the string into the string stack */ - - src = (ubyte*)&GETSTACK(st, addr1); /* Pointer to original string */ - memcpy(dest, src, uparm1); - - /* Update the stack content */ - - TOS(st, 1) = addr2 + sSTRING_HDR_SIZE; - break; - - /* Replace a character with a string residing in allocated string stack. - * function mkstkc(c : char) : string; - * ON INPUT - * TOS(st, 0)=Character value - * ON RETURN - * TOS(st, 0)=length of new string - * TOS(st, 1)=pointer to new string - */ - - case lbMKSTKC : - /* Check if there is space on the string stack for the new string - * FIXME: This logic does not handle strings with other than the - * default size! - */ - - if (st->csp + sSTRING_SIZE >= st->spb) - { - return eSTRSTKOVERFLOW; - } - - /* Allocate space on the string stack for the new string */ - - addr2 = ((st->csp + 1) & ~1); - st->csp += sSTRING_SIZE; /* Allocate max size */ - - /* Save the length at the beginning of the copy */ - - tmp = (uint16*)&GETSTACK(st, addr2); /* Pointer to new string */ - *tmp++ = 1; /* Save initial size */ - dest = (ubyte*)tmp; /* Pointer to string data */ - - /* Copy the character into the string stack */ - - *dest++ = TOS(st, 0); /* Save character as string */ - - /* Update the stack content */ - - TOS(st, 0) = addr2 + sSTRING_HDR_SIZE; /* String address */ - PUSH(st, 1); /* String length */ - break; - - /* Concatenate a string to the end of a string. - * function strcat(name : string, c : char) : string; - * - * ON INPUT - * TOS(st, 0)=length of string1 - * TOS(st, 1)=pointer to string1 data - * TOS(st, 2)=length of string2 - * TOS(st, 3)=pointer to string2 data - * ON OUTPUT - * TOS(st, 1)=new length of string2 - * TOS(st, 2)=pointer to string2 - */ - - case lbSTRCAT : - /* Get the parameters from the stack (leaving the string reference - * in place. - */ - - POP(st, uparm1); /* string1 size */ - POP(st, addr1); /* string1 data stack addr */ - uparm2 = TOS(st, 0); /* string2 size */ - - /* Check for string overflow. FIXME: This logic does not handle - * strings with other than the default size! - */ - - if (uparm1 + uparm2 > sSTRING_MAX_SIZE) - return eSTRSTKOVERFLOW; - else - { - /* Get a pointer to string1 data */ - - src = ATSTACK(st, addr1); - - /* Get a pointer to string2 header, set new size then, get - * a pointer to string2 data. - */ - - tmp = ((uint16*)&GETSTACK(st, TOS(st, 1))) - 1; - *tmp++ = uparm1 + uparm2; - dest = (ubyte*)tmp; - - memcpy(&dest[uparm2], src, uparm1); /* cat strings */ - TOS(st, 0) = uparm1 + uparm2; /* Save new size */ - } - break; - - /* Concatenate a character to the end of a string. - * function strcatc(name : string, c : char) : string; - * - * ON INPUT - * TOS(st, 0)=character to concatenate - * TOS(st, 1)=length of string - * TOS(st, 2)=pointer to string - * ON OUTPUT - * TOS(st, 1)=new length of string - * TOS(st, 2)=pointer to string - */ - - case lbSTRCATC : - /* Get the parameters from the stack (leaving the string reference - * in place. - */ - - POP(st, uparm1); /* Character to concatenate */ - uparm2 = TOS(st, 0); /* Current length of string */ - - /* Check for string overflow. FIXME: This logic does not handle - * strings with other than the default size! - */ - - if (uparm2 >= sSTRING_MAX_SIZE) - return eSTRSTKOVERFLOW; - else - { - /* Get a pointer to string header, set size new size then, get - * a pointer to string data. - */ - - tmp = ((uint16*)&GETSTACK(st, TOS(st, 1))) - 1; - *tmp++ = uparm2 + 1; - dest = (ubyte*)tmp; - - /* Add the new charcter */ - - dest[uparm2] = (ubyte)uparm1; - - /* Save the new string size */ - - TOS(st, 0) = uparm2 + 1; - } - break; - - /* Compare two pascal strings - * function strcmp(name1 : string, name2 : string) : integer; - * ON INPUT - * TOS(st, 1)=length of string2 - * TOS(st, 2)=address of string2 data - * TOS(st, 3)=length of string1 - * TOS(st, 4)=address of string1 data - * ON OUTPUT - * TOS(st, 0)=(-1=less than, 0=equal, 1=greater than} - */ - - case lbSTRCMP : - { - int result; - - /* Get the parameters from the stack (leaving space for the - * return value); - */ - - POP(st, uparm2); /* length of string2 */ - POP(st, addr2); /* address of string2 data */ - POP(st, uparm1); /* length of string1 */ - addr1 = TOS(st, 0); /* address of string1 data */ - - /* Get full address */ - - dest = ATSTACK(st, addr1); - src = ATSTACK(st, addr2); - - /* If name1 is shorter than name2, then we can only return - * -1 (less than) or +1 greater than. If the substrings - * of length of name1 are equal, then we return less than. - */ - - if (uparm1 < uparm2) - { - result = memcmp(dest, src, uparm1); - if (result == 0) result = -1; - } - - /* If name1 is longer than name2, then we can only return - * -1 (less than) or +1 greater than. If the substrings - * of length of name2 are equal, then we return greater than. - */ - - else if (uparm1 > uparm2) - { - result = memcmp(dest, src, uparm2); - if (result == 0) result = 1; - } - - /* The strings are of equal length. Return the result of - * the comparison. - */ - - else - { - result = memcmp(dest, src, uparm1); - } - TOS(st, 0) = result; - } - break; - - default : - return eBADSYSLIBCALL; - - } - - return eNOERROR; - -} /* end pexec_libcall */ - -/**************************************************************************** - * Name: pexec_execfp - * - * Description: - * This function processes a floating point operation. - * - ****************************************************************************/ - -static uint16 pexec_execfp(struct pexec_s *st, ubyte fpop) -{ - sint16 intValue; - fparg_t arg1; - fparg_t arg2; - fparg_t result; - - switch (fpop & fpMASK) - { - /* Floating Pointer Conversions (On stack argument: FP or Integer) */ - - case fpFLOAT : - POP(st, intValue); - result.f = (float64)intValue; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - - case fpTRUNC : - case fpROUND : - pexec_getfparguments(st, fpop, &arg1, NULL); - intValue = (sint16)arg1.f; - PUSH(st, intValue); - break; - - /* Floating Point arithmetic instructions (Two FP stack arguments) */ - - case fpADD : - pexec_getfparguments(st, fpop, &arg1, &arg2); - result.f = arg1.f + arg2.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpSUB : - pexec_getfparguments(st, fpop, &arg1, &arg2); - result.f = arg1.f - arg2.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpMUL : - pexec_getfparguments(st, fpop, &arg1, &arg2); - result.f = arg1.f * arg2.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpDIV : - pexec_getfparguments(st, fpop, &arg1, &arg2); - result.f = arg1.f / arg2.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpMOD : - return eBADFPOPCODE; -#if 0 /* Not yet */ - pexec_getfparguments(st, fpop, &arg1, &arg2); - result.f = arg1.f % arg2.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; -#endif - - /* Floating Point Comparisons (Two FP stack arguments) */ - - case fpEQU : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f == arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - case fpNEQ : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f != arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - case fpLT : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f < arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - case fpGTE : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f >= arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - case fpGT : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f > arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - case fpLTE : - pexec_getfparguments(st, fpop, &arg1, &arg2); - intValue = PFALSE; - if (arg1.f <= arg2.f) - intValue = PTRUE; - PUSH(st, intValue); - break; - - /* Floating Point arithmetic instructions (One FP stack arguments) */ - - case fpNEG : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = -arg1.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; -#ifdef CONFIG_HAVE_LIBM - case fpABS : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = fabs(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; -#endif - case fpSQR : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = arg1.f * arg1.f; - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; -#ifdef CONFIG_HAVE_LIBM - case fpSQRT : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = sqrt(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpSIN : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = sin(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpCOS : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = cos(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpATAN : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = atan(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpLN : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = log(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; - case fpEXP : - pexec_getfparguments(st, fpop, &arg1, NULL); - result.f = exp(arg1.f); - PUSH(st, result.hw[0]); - PUSH(st, result.hw[1]); - PUSH(st, result.hw[2]); - PUSH(st, result.hw[3]); - break; -#endif - - default : - return eBADFPOPCODE; - - } - return eNOERROR; - -} /* end pexec_execfp */ - -/**************************************************************************** - * Name: pexec_getfparguments - * - * Description: - * This function retrieves the floating point arguments and performs - * integer to REAL conversions as necessary - * - ****************************************************************************/ - -static void pexec_getfparguments(struct pexec_s *st, ubyte fpop, fparg_t *arg1, fparg_t *arg2) -{ - sint16 sparm; - - /* Extract arg2 from the stack */ - - if (arg2) - { - /* Convert an integer argument to type REAL */ - - if ((fpop & fpARG2) != 0) - { - POP(st, sparm); - arg2->f = (float64)sparm; - } - else - { - POP(st, arg2->hw[3]); - POP(st, arg2->hw[2]); - POP(st, arg2->hw[1]); - POP(st, arg2->hw[0]); - } - } - - /* Extract arg1 from the stack */ - - if (arg1) - { - /* Convert an integer argument to type REAL */ - - if ((fpop & fpARG1) != 0) - { - POP(st, sparm); - arg1->f = (float64)sparm; - } - else - { - POP(st, arg1->hw[3]); - POP(st, arg1->hw[2]); - POP(st, arg1->hw[1]); - POP(st, arg1->hw[0]); - } - } - -} /* end pexec_getfparguments */ - -/**************************************************************************** - * Name: pexec_readinteger - * - * Description: - * This function parses a decimal integer from ioptr - ****************************************************************************/ - -static ustack_t pexec_readinteger(ubyte *ioptr) -{ - sstack_t value = 0; - - while (isspace(*ioptr)) ioptr++; - while ((*ioptr >= '0') && (*ioptr <= '9')) - { - value = 10*value - + (sstack_t)(*ioptr) - - (sstack_t)'0'; - ioptr++; - } - - return (ustack_t)value; - -} /* end pexec_readinteger */ - -/**************************************************************************** - * Name: pexec_readreal - * - * Description: - * This function parses a decimal integer from ioptr. - * - ****************************************************************************/ - -static void pexec_readreal(uint16 *dest, ubyte *inPtr) -{ - sint32 intpart; - fparg_t result; - float64 fraction; - ubyte unaryop; - - intpart = 0; - unaryop = '+'; - - /* Check for a leading unary - */ - - if ((*inPtr == '-') || (*inPtr == '+')) - unaryop = *inPtr++; - - /* Get the integer part of the real */ - - while ((*inPtr >= '0') && (*inPtr <= '9')) - intpart = 10*intpart + ((sint32)*inPtr++) - ((sint32)'0'); - - result.f = ((float64)intpart); - - /* Check for the a fractional part */ - - if (*inPtr == '.') - { - inPtr++; - fraction = 0.1; - while ((*inPtr >= '0') && (*inPtr <= '9')) - { - result.f += fraction * (float64)(((sint32)*inPtr++) - ((sint32)'0')); - fraction /= 10.0; - } - } - - /* Correct the sign of the result */ - - if (unaryop == '-') - result.f = -result.f; - - /* Return the value into the P-Machine stack */ - - *dest++ = result.hw[0]; - *dest++ = result.hw[1]; - *dest++ = result.hw[2]; - *dest = result.hw[3]; - -} /* end pexec_readreal */ - -/**************************************************************************** - * Name: pexec_getbaseaddress - * - * Description: - * This function binds the base address corresponding to a given level - * offset. - * - ****************************************************************************/ - -static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset) -{ - /* Start with the base register of the current frame */ - - ustack_t baseAddress = st->fp; - - /* Search backware "leveloffset" frames until the correct frame is - * found - */ - - while (leveloffset > 0) - { - baseAddress = st->dstack.i[BTOISTACK(baseAddress)]; - leveloffset--; - } - - /* Offset that value by two words (one for the st->fp and one for the - * return value - */ - - return baseAddress + 2*BPERI; - -} /* end pexec_getbaseaddress */ - -/**************************************************************************** - * Name: pexec_mkcstring - ****************************************************************************/ - -static ubyte *pexec_mkcstring(ubyte *buffer, int buflen) -{ - ubyte *string; - - string = malloc(buflen + 1); - if (string != NULL) - { - memcpy(string, buffer, buflen); - string[buflen] = '\0'; - } - return string; -} - -/**************************************************************************** - * Name: pexec8 - * - * Descripton: - * Handle 8-bit instructions with no immediate data - * - ****************************************************************************/ - -static inline int pexec8(FAR struct pexec_s *st, ubyte opcode) -{ - sstack_t sparm; - ustack_t uparm1; - ustack_t uparm2; - ustack_t uparm3; - - switch (opcode) - { - /* Arithmetic & logical & and integer conversions (One stack argument) */ - case oNEG : - TOS(st, 0) = (ustack_t)(-(sstack_t)TOS(st, 0)); - break; - case oABS : - if (signExtend16(TOS(st, 0)) < 0) - { - TOS(st, 0) = (ustack_t)(-signExtend16(TOS(st, 0))); - } - break; - case oINC : - TOS(st, 0)++; - break; - case oDEC : - TOS(st, 0)--; - break; - case oNOT : - TOS(st, 0) = ~TOS(st, 0); - break; - - /* Arithmetic & logical (Two stack arguments) */ - - case oADD : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) + sparm); - break; - case oSUB : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) - sparm); - break; - case oMUL : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) * sparm); - break; - case oDIV : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) / sparm); - break; - case oMOD : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) % sparm); - break; - case oSLL : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) << sparm); - break; - case oSRL : - POP(st, sparm); - TOS(st, 0) = (TOS(st, 0) >> sparm); - break; - case oSRA : - POP(st, sparm); - TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) >> sparm); - break; - case oOR : - POP(st, uparm1); - TOS(st, 0) = (TOS(st, 0) | uparm1); - break; - case oAND : - POP(st, uparm1); - TOS(st, 0) = (TOS(st, 0) & uparm1); - break; - case oBIT : - POP(st, uparm1); - uparm2 = TOS(st, 0); - if ((uparm1 & (1 << uparm2)) != 0) - { - TOS(st, 0) = PTRUE; - } - else - { - TOS(st, 0) = PFALSE; - } - break; - - /* Comparisons (One stack argument) */ - - case oEQUZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm == 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - case oNEQZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm != 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - case oLTZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm < 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - case oGTEZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm >= 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - case oGTZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm > 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - case oLTEZ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm <= 0) - { - uparm1 = PTRUE; - } - PUSH(st, uparm1); - break; - - /* Comparisons (Two stack arguments) */ - - case oEQU : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm == (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - case oNEQ : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm != (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - case oLT : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm < (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - case oGTE : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm >= (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - case oGT : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm > (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - case oLTE : - POP(st, sparm); - uparm1 = PFALSE; - if (sparm <= (sstack_t)TOS(st, 0)) - { - uparm1 = PTRUE; - } - TOS(st, 0) = uparm1; - break; - - /* Load (One stack argument) */ - - case oLDI : - POP(st, uparm1); /* Address */ - PUSH(st, GETSTACK(st, uparm1)); - PUSH(st, GETSTACK(st, uparm1 + BPERI)); - break; - case oLDIH : - TOS(st, 0) = GETSTACK(st, TOS(st, 0)); - break; - case oLDIB : - TOS(st, 0) = GETBSTACK(st, TOS(st, 0)); - break; - case oLDIM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size */ - POP(st, uparm2); /* Stack offset */ - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUSH(st, GETSTACK(st, uparm2)); - uparm2 += BPERI; - uparm1 -= BPERI; - } - else - { - PUSH(st, GETBSTACK(st, uparm2)); - uparm2++; - uparm1--; - } - } - break; - case oDUP : - uparm1 = TOS(st, 0); - uparm2 = TOS(st, 1); - PUSH(st, uparm2); - PUSH(st, uparm1); - break; - case oDUPH : - uparm1 = TOS(st, 0); - PUSH(st, uparm1); - break; - case oPUSHS : - PUSH(st, st->csp); - break; - case oPOPS : - POP(st, st->csp); - break; - - /* Store (Two stack arguments) */ - - case oSTIH : - POP(st, uparm1); - POP(st, uparm2); - PUTSTACK(st, uparm1,uparm2); - break; - case oSTIB : - POP(st, uparm1); - POP(st, uparm2); - PUTBSTACK(st, uparm1, uparm2); - break; - case oSTIM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size in bytes */ - uparm3 = uparm1; /* Save for stack discard */ - sparm = ROUNDBTOI(uparm1); /* Size in words */ - uparm2 = TOS(st, sparm); /* Stack offset */ - sparm--; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUTSTACK(st, TOS(st, sparm), uparm2); - uparm2 += BPERI; - uparm1 -= BPERI; - sparm--; - } - else - { - PUTBSTACK(st, TOS(st, sparm), uparm2); - uparm2++; - uparm1--; - } - } - - /* Discard the stored data + the stack offset */ - - DISCARD(st, (ROUNDBTOI(uparm3) + 1)); - break; - - /* Program control (No stack arguments) */ - - case oNOP : - break; - case oRET : - POP(st, st->pc); - POP(st, st->fp); - DISCARD(st, 1); - return eNOERROR; - - /* System Functions (No stack arguments) */ - - case oEND : - return eEXIT; - - default : - return eILLEGALOPCODE; - } - - st->pc += 1; - return eNOERROR; -} - -/**************************************************************************** - * Name: pexec16 - * - * Descripton: - * Handle 16-bit instructions with 8-bits of immediate data (imm8) - * - ****************************************************************************/ - -static inline int pexec16(FAR struct pexec_s *st, ubyte opcode, ubyte imm8) -{ - int ret = eNOERROR; - - st->pc += 2; - switch (opcode) - { - /* Data stack: imm8 = 8 bit unsigned data (no stack arguments) */ - - case oPUSHB : - PUSH(st, imm8); - break; - - /* Floating Point: imm8 = FP op-code (varying number of stack arguments) */ - case oFLOAT : - ret = pexec_execfp(st, imm8); - break; - - default : - ret = eILLEGALOPCODE; - break; - } - return ret; -} - -/**************************************************************************** - * Name: pexec24 - * - * Descripton: - * Handle 24-bit instructions with 16-bits of immediate data (imm16) - * - ****************************************************************************/ - -static inline int pexec24(FAR struct pexec_s *st, ubyte opcode, uint16 imm16) -{ - sstack_t sparm1; - sstack_t sparm2; - ustack_t uparm1; - ustack_t uparm2; - ustack_t uparm3; - int ret = eNOERROR; - - switch (opcode) - { - /* Program control: imm16 = unsigned label (no stack arguments) */ - - case oJMP : - goto branch_out; - - /* Program control: imm16 = unsigned label (One stack argument) */ - - case oJEQUZ : - POP(st, sparm1); - if (sparm1 == 0) - { - goto branch_out; - } - break; - case oJNEQZ : - POP(st, sparm1); - if (sparm1 != 0) - { - goto branch_out; - } - break; - case oJLTZ : - POP(st, sparm1); - if (sparm1 < 0) - { - goto branch_out; - } - break; - case oJGTEZ : - POP(st, sparm1); - if (sparm1 >= 0) - { - goto branch_out; - } - break; - case oJGTZ : - POP(st, sparm1); - if (sparm1 > 0) - { - goto branch_out; - } - break; - case oJLTEZ : - POP(st, sparm1); - if (sparm1 <= 0) - { - goto branch_out; - } - break; - - /* Program control: imm16 = unsigned label (Two stack arguments) */ - - case oJEQU : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 == sparm1) - { - goto branch_out; - } - break; - case oJNEQ : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 != sparm1) - { - goto branch_out; - } - break; - case oJLT : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 < sparm1) - { - goto branch_out; - } - break; - case oJGTE : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 >= sparm1) - { - goto branch_out; - } - break; - case oJGT : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 > sparm1) - { - goto branch_out; - } - break; - case oJLTE : - POP(st, sparm1); - POP(st, sparm2); - if (sparm2 <= sparm1) - { - goto branch_out; - } - break; - - /* Load: imm16 = usigned offset (no stack arguments) */ - - case oLD : - uparm1 = st->spb + imm16; - PUSH(st, GETSTACK(st, uparm1)); - PUSH(st, GETSTACK(st, uparm1 + BPERI)); - break; - case oLDH : - uparm1 = st->spb + imm16; - PUSH(st, GETSTACK(st, uparm1)); - break; - case oLDB : - uparm1 = st->spb + imm16; - PUSH(st, GETBSTACK(st, uparm1)); - break; - case oLDM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); - uparm2 = st->spb + imm16; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUSH(st, GETSTACK(st, uparm2)); - uparm2 += BPERI; - uparm1 -= BPERI; - } - else - { - PUSH(st, GETBSTACK(st, uparm2)); - uparm2++; - uparm1--; - } - } - break; - - /* Load & store: imm16 = unsigned base offset (One stack argument) */ - - case oST : - uparm1 = st->spb + imm16; - POP(st, uparm2); - PUTSTACK(st, uparm2, uparm1 + BPERI); - POP(st, uparm2); - PUTSTACK(st, uparm2, uparm1); - break; - case oSTH : - uparm1 = st->spb + imm16; - POP(st, uparm2); - PUTSTACK(st, uparm2, uparm1); - break; - case oSTB : - uparm1 = st->spb + imm16; - POP(st, uparm2); - PUTBSTACK(st, uparm2, uparm1); - break; - case oSTM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size */ - uparm3 = uparm1; /* Save for stack discard */ - uparm2 = st->spb + imm16; - sparm1 = ROUNDBTOI(uparm1) - 1; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUTSTACK(st, TOS(st, sparm1), uparm2); - uparm2 += BPERI; - uparm1 -= BPERI; - sparm1--; - } - else - { - PUTBSTACK(st, TOS(st, sparm1), uparm2); - uparm2++; - uparm1--; - } - } - - /* Discard the stored data */ - - DISCARD(st, ROUNDBTOI(uparm3)); - break; - case oLDX : - uparm1 = st->spb + imm16 + TOS(st, 0); - TOS(st, 0) = GETSTACK(st, uparm1); - PUSH(st, GETSTACK(st, uparm1 + BPERI)); - break; - case oLDXH : - uparm1 = st->spb + imm16 + TOS(st, 0); - TOS(st, 0) = GETSTACK(st, uparm1); - break; - case oLDXB : - uparm1 = st->spb + imm16 + TOS(st, 0); - TOS(st, 0) = GETBSTACK(st, uparm1); - break; - case oLDXM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); - POP(st, uparm2); - uparm2 += st->spb + imm16; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUSH(st, GETSTACK(st, uparm2)); - uparm2 += BPERI; - uparm1 -= BPERI; - } - else - { - PUSH(st, GETBSTACK(st, uparm2)); - uparm2++; - uparm1--; - } - } - break; - - /* Store: imm16 = unsigned base offset (Two stack arguments) */ - - case oSTXH : - POP(st, uparm1); - POP(st, uparm2); - uparm2 += st->spb + imm16; - PUTSTACK(st, uparm1,uparm2); - break; - case oSTXB : - POP(st, uparm1); - POP(st, uparm2); - uparm2 += st->spb + imm16; - PUTBSTACK(st, uparm1, uparm2); - break; - case oSTXM : -/* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size */ - uparm3 = uparm1; /* Save for stack discard */ - sparm1 = ROUNDBTOI(uparm1); /* Size in 16-bit words */ - uparm2 = TOS(st, sparm1); /* index */ - sparm1--; - uparm2 += st->spb + imm16; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUTSTACK(st, TOS(st, sparm1), uparm2); - uparm2 += BPERI; - uparm1 -= BPERI; - sparm1--; - } - else - { - PUTBSTACK(st, TOS(st, sparm1), uparm2); - uparm2++; - uparm1--; - } - } - - /* Discard the stored data + the index */ - - DISCARD(st, (ROUNDBTOI(uparm3) + 1)); - break; - - case oLA : - uparm1 = st->spb + imm16; - PUSH(st, uparm1); - break; - case oLAX : - TOS(st, 0) = st->spb + imm16 + TOS(st, 0); - break; - - /* Data stack: imm16 = 16 bit signed data (no stack arguments) */ - - case oPUSH : - PUSH(st, imm16); - break; - case oINDS : - st->sp += signExtend16(imm16); - break; - - /* System Functions: - * For LIB: imm16 = sub-function code - */ - - case oLIB : - ret = pexec_libcall(st, imm16); - break; - - /* Program control: imm16 = unsigned label (no stack arguments) */ - - case oLAC : - uparm1 = imm16 + st->rop; - PUSH(st, uparm1); - break; - - case oLABEL : - default: - ret = eILLEGALOPCODE; - break; - } - - st->pc += 3; - return ret; - -branch_out: - st->pc = (addr_t)imm16; - return ret; -} - -/**************************************************************************** - * Name: pexec32 - * - * Descripton: - * Handle 32-bit instructions with 24-bits of immediate data (imm8+imm16) - * - ****************************************************************************/ - -static int pexec32(FAR struct pexec_s *st, ubyte opcode, ubyte imm8, uint16 imm16) -{ - sstack_t sparm; - ustack_t uparm1; - ustack_t uparm2; - ustack_t uparm3; - int ret = eNOERROR; - - switch (opcode) - { - /* Load: imm8 = level; imm16 = signed frame offset (no stack arguments) */ - case oLDS : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUSH(st, GETSTACK(st, uparm1)); - PUSH(st, GETSTACK(st, uparm1 + BPERI)); - break; - case oLDSH : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUSH(st, GETSTACK(st, uparm1)); - break; - case oLDSB : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUSH(st, GETBSTACK(st, uparm1)); - break; - case oLDSM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); - uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUSH(st, GETSTACK(st, uparm2)); - uparm2 += BPERI; - uparm1 -= BPERI; - } - else - { - PUSH(st, GETBSTACK(st, uparm2)); - uparm2++; - uparm1--; - } - } - break; - - /* Load & store: imm8 = level; imm16 = signed frame offset (One stack argument) */ - - case oSTSH : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - POP(st, uparm2); - PUTSTACK(st, uparm2, uparm1); - break; - case oSTSB : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - POP(st, uparm2); - PUTBSTACK(st, uparm2, uparm1); - break; - case oSTSM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size */ - uparm3 = uparm1; /* Save for stack discard */ - uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - sparm = ROUNDBTOI(uparm1) - 1; - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUTSTACK(st, TOS(st, sparm), uparm2); - uparm2 += BPERI; - uparm1 -= BPERI; - sparm--; - } - else - { - PUTBSTACK(st, TOS(st, sparm), uparm2); - uparm2++; - uparm1--; - } - } - - /* Discard the stored data */ - - DISCARD(st, ROUNDBTOI(uparm3)); - break; - case oLDSX : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); - TOS(st, 0) = GETSTACK(st, uparm1); - PUSH(st, GETSTACK(st, uparm1 + BPERI)); - break; - case oLDSXH : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); - TOS(st, 0) = GETSTACK(st, uparm1); - break; - case oLDSXB : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); - TOS(st, 0) = GETBSTACK(st, uparm1); - break; - case oLDSXM : - /* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); - POP(st, uparm2); - uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUSH(st, GETSTACK(st, uparm2)); - uparm2 += BPERI; - uparm1 -= BPERI; - } - else - { - PUSH(st, GETBSTACK(st, uparm2)); - uparm2++; - uparm1--; - } - } - break; - - /* Store: imm8 = level; imm16 = signed frame offset (Two stack arguments) */ - - case oSTSXH : - POP(st, uparm1); - POP(st, uparm2); - uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUTSTACK(st, uparm1,uparm2); - break; - case oSTSXB : - POP(st, uparm1); - POP(st, uparm2); - uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUTBSTACK(st, uparm1, uparm2); - break; - case oSTSXM : -/* FIX ME --> Need to handle the unaligned case */ - POP(st, uparm1); /* Size */ - uparm3 = uparm1; /* Save for stack discard */ - sparm = ROUNDBTOI(uparm1); /* Size in 16-bit words */ - uparm2 = TOS(st, sparm); /* index */ - sparm--; - uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - while (uparm1 > 0) - { - if (uparm1 >= BPERI) - { - PUTSTACK(st, TOS(st, sparm), uparm2); - uparm2 += BPERI; - uparm1 -= BPERI; - sparm--; - } - else - { - PUTBSTACK(st, TOS(st, sparm), uparm2); - uparm2++; - uparm1--; - } - } - - /* Discard the stored data + the index */ - - DISCARD(st, (ROUNDBTOI(uparm3) + 1)); - break; - - case oLAS : - uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); - PUSH(st, uparm1); - break; - case oLASX : - TOS(st, 0) = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); - break; - - /* Program Control: imm8 = level; imm16 = unsigned label (No - * stack arguments) - */ - - case oPCAL : - PUSH(st, pexec_getbaseaddress(st, imm8)); - PUSH(st, st->fp); - uparm1 = st->sp; - PUSH(st, st->pc + 4); - st->fp = uparm1; - st->pc = (addr_t)imm16; - return eNOERROR; - - /* System Functions: - * For SYSIO: imm8 = file number; imm16 = sub-function code - */ - - case oSYSIO : - ret = pexec_sysio(st, imm8, imm16); - break; - - /* Psuedo-operations: (No stack arguments) - * For LINE: imm8 = file number; imm16 = line number - */ - - case oLINE : - default : - ret = eILLEGALOPCODE; - break; - } - - st->pc += 4; - return ret; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pexec_init - ****************************************************************************/ - -FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr) -{ - struct pexec_s *st; - addr_t stacksize; - addr_t adjusted_rosize; - - /* Allocate the p-machine state stucture */ - - st = (struct pexec_s *)malloc(sizeof(struct pexec_s)); - if (!st) - { - return NULL; - } - - /* Set up I-Space */ - - st->ispace = attr->ispace; - st->maxpc = attr->maxpc; - - /* Align size of read-only data to 16-bit boundary. */ - - adjusted_rosize = (attr->rosize + 1) & ~1; - - /* Allocate the pascal stack. Organization is string stack, then - * constant data, then "normal" pascal stack. - */ - - stacksize = attr->varsize + adjusted_rosize + attr->strsize; - st->dstack.b = (ubyte*)malloc(stacksize); - if (!st->dstack.b) - { - free(st); - return NULL; - } - - /* Copy the rodata into the stack */ - - if (attr->rodata && attr->rosize) - { - memcpy(&st->dstack.b[attr->strsize], attr->rodata, attr->rosize); - } - - /* Set up info needed to perform a simulated reset */ - - st->strsize = attr->strsize; - st->rosize = adjusted_rosize; - st->entry = attr->entry; - st->stacksize = stacksize; - - /* Then perform a simulated reset */ - - pexec_reset(st); - return st; -} - -/**************************************************************************** - * Name: pexec - ****************************************************************************/ - -int pexec(FAR struct pexec_s *st) -{ - ubyte opcode; - int ret; - - /* Make sure that the program counter is within range */ - - if (st->pc >= st->maxpc) - { - ret = eBADPC; - } - else - { - /* Get the instruction to execute */ - - opcode = st->ispace[st->pc]; - if ((opcode & o8) != 0) - { - /* Get the immediate, 8-bit value */ - - ubyte imm8 = st->ispace[st->pc + 1]; - if ((opcode & o16) != 0) - { - /* Get the immediate, big-endian 16-bit value */ - - uint16 imm16 = ((st->ispace[st->pc + 2]) << 8) | st->ispace[st->pc + 3]; - - /* Handle 32 bit instructions */ - - ret = pexec32(st, opcode, imm8, imm16); - } - else - { - /* Handle 16-bit instructions */ - - ret = pexec16(st, opcode, imm8); - } - } - else if ((opcode & o16) != 0) - { - /* Get the immediate, big-endian 16-bit value */ - - uint16 imm16 = ((st->ispace[st->pc + 1]) << 8) | st->ispace[st->pc + 2]; - - /* Handle 24-bit instructions */ - - ret = pexec24(st, opcode, imm16); - } - else - { - /* Handle 8-bit instructions */ - - ret = pexec8(st, opcode); - } - } - return ret; -} - -/**************************************************************************** - * Name: pexec_reset - ****************************************************************************/ - -void pexec_reset(struct pexec_s *st) -{ - int dndx; - - /* Setup the bottom of the "normal" pascal stack */ - - st->rop = st->strsize; - st->spb = st->strsize + st->rosize; - - /* Initialize the emulated P-Machine registers */ - - st->csp = 0; - st->sp = st->spb + 2*BPERI; - st->fp = st->spb + BPERI; - st->pc = st->entry; - - /* Initialize the P-Machine stack */ - - dndx = BTOISTACK(st->spb); - st->dstack.i[dndx] = 0; - st->dstack.i[dndx+1] = 0; - st->dstack.i[dndx+2] = -1; -} - -/**************************************************************************** - * Name: pexec_release - ****************************************************************************/ - -void pexec_release(struct pexec_s *st) -{ - if (st) - { - if (st->dstack.i) - { - free(st->dstack.i); - } - - if (st->ispace) - { - free(st->ispace); - } - - free(st); - } -} +/**************************************************************************** + * pexec.c + * + * Copyright (C) 200-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn16.h" +#include "pfdefs.h" +#include "pxdefs.h" +#include "pedefs.h" + +#include "paslib.h" +#include "pexec.h" + +#ifdef CONFIG_HAVE_LIBM +#include +#endif + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define PTRUE ((ustack_t)-1) +#define PFALSE ((ustack_t) 0) + +/**************************************************************************** + * Macros + ****************************************************************************/ + +/* Remove the value from the top of the stack */ + +#define POP(st, dest) \ + do { \ + dest = (st)->dstack.i[BTOISTACK((st)->sp)]; \ + (st)->sp -= BPERI; \ + } while (0) + +/* Add the value to top of the stack */ + +#define PUSH(st, src) \ + do { \ + (st)->sp += BPERI; \ + (st)->dstack.i[BTOISTACK((st)->sp)] = src; \ + } while (0) + +/* Return an rvalue for the (word) offset from the top of the stack */ + +#define TOS(st, off) \ + (st)->dstack.i[BTOISTACK((st)->sp)-(off)] + +/* Save the src (word) at the dest (word) stack position */ + +#define PUTSTACK(st, src, dest) \ + do { \ + (st)->dstack.i[BTOISTACK(dest)] = src; \ + } while (0) + +/* Return an rvalue for the (word) from the absolute stack position */ + +#define GETSTACK(st, src) \ + (st)->dstack.i[BTOISTACK(src)] + +/* Store a byte to an absolute (byte) stack position */ + +#define PUTBSTACK(st, src,dest) \ + do { \ + (st)->dstack.b[dest] = dest; \ + } while (0) + +/* Return an rvalue for the absolute (byte) stack position */ + +#define GETBSTACK(st, src) \ + (st)->dstack.b[src] + +/* Return the address for an absolute (byte) stack position. */ + +#define ATSTACK(st, src) \ + &(st)->dstack.b[src] + +/* Discard n words from the top of the stack */ + +#define DISCARD(st, n) \ + do { \ + (st)->sp -= BPERI*(n); \ + } while (0) + +/* Release a C string */ + +#define free_cstring(a) \ + free(a) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +union fparg_u +{ + double f; + uint16_t hw[4]; +}; + +typedef union fparg_u fparg_t; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint16_t pexec_sysio(struct pexec_s *st, uint8_t fileno, uint16_t subfunc); +static uint16_t pexec_libcall(struct pexec_s *st, uint16_t subfunc); +static uint16_t pexec_execfp(struct pexec_s *st, uint8_t fpop); +static void pexec_getfparguments(struct pexec_s *st, uint8_t fpop, fparg_t *arg1, fparg_t *arg2); +static ustack_t pexec_readinteger(uint8_t *ioptr); +static void pexec_readreal(uint16_t *dest, uint8_t *ioptr); +static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset); +static uint8_t *pexec_mkcstring(uint8_t *buffer, int buflen); + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +static uint8_t ioline[LINE_SIZE+1]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pexec_sysio + * + * Description: + * This function process a system I/O operation. + * + ****************************************************************************/ + +static uint16_t pexec_sysio(struct pexec_s *st, uint8_t fileno, uint16_t subfunc) +{ + ustack_t uparm1; + fparg_t fp; + + uint8_t *ptr; + + switch (subfunc) + { + case xEOF : +/* FINISH ME -- > */ + break; + case xEOLN : +/* FINISH ME -- > */ + break; + case xRESET : +/* FINISH ME -- > */ + break; + case xREWRITE : +/* FINISH ME -- > */ + break; + + case xREADLN : +/* FINISH ME -- > */ + break; + case xREAD_BINARY : +/* FINISH ME -- > */ + break; + + /* xREAD_INT: + * STACK INPUTS: TOS(st, 0) = address to store integer */ + case xREAD_INT : + (void)fgets((char*)ioline, LINE_SIZE, stdin); + PUTSTACK(st, pexec_readinteger(ioline),TOS(st, 0)); + break; + + /* xREAD_CHAR: + * STACK INPUTS: TOS(st, 0) = address to store integer */ + + case xREAD_CHAR: + (void)fgets((char*)ioline, LINE_SIZE, stdin); + PUTBSTACK(st, ioline[0],TOS(st, 0)); + break; + + /* XREAD_STRING: + + * STACK INPUTS: + * TOS = Number of bytes to read + * TOS-1 = Address to store byte(s) */ + case xREAD_STRING : + (void)fgets((char*)ATSTACK(st, TOS(st, 1)), TOS(st, 0), stdin); + break; + + /* xREAD_REAL: + * STACK INPUTS: TOS = address to store REAL */ + + case xREAD_REAL : + (void)fgets((char*)ioline, LINE_SIZE, stdin); + pexec_readreal((uint16_t*)ATSTACK(st, TOS(st, 0)), ioline); + break; + + case xWRITELN : + putchar('\n'); + break; + case xWRITE_PAGE : + putchar('\f'); + break; + case xWRITE_BINARY : +/* FINISH ME -- > */ + break; + + /* xWRITE_INT: + * STACK INPUTS: TOS = integer value to write. */ + + case xWRITE_INT : + printf("%ld", signExtend16(TOS(st, 0))); + break; + + /* xWRITE_CHAR: + * STACK INPUTS: TOS = char value to write. */ + + case xWRITE_CHAR : + putchar(TOS(st, 0)); + break; + + /* xWRITE_STRING: + * STACK INPUTS: + * TOS = Number of bytes to write + * TOS-1 = Address of src data */ + + case xWRITE_STRING : + uparm1 = TOS(st, 0); + for (ptr = (uint8_t*)ATSTACK(st, TOS(st, 1)); uparm1; uparm1--, ptr++) + putchar(*ptr); + break; + + /* xWRITE_REAL: + * STACK INPUTS: TOS = value of double */ + + case xWRITE_REAL : + fp.hw[0] = TOS(st, 3); + fp.hw[1] = TOS(st, 2); + fp.hw[2] = TOS(st, 1); + fp.hw[3] = TOS(st, 0);; + printf("%f", fp.f); + break; + + default : + return eBADSYSIOFUNC; + + } + + return eNOERROR; + +} /* end pexec_sysio */ + +/**************************************************************************** + * Name: pexec_libcall + * + * Description: + * This function process a system I/O operation + * + ****************************************************************************/ + +static uint16_t pexec_libcall(struct pexec_s *st, uint16_t subfunc) +{ + ustack_t uparm1; + ustack_t uparm2; + addr_t addr1; + addr_t addr2; + uint16_t *tmp; + uint16_t *ref; + uint8_t *src; + uint8_t *dest; + uint8_t *name; + int len; + int32_t value; + + switch (subfunc) + { + /* Get the value of an environment string + * + * ON INPUT: + * TOS(st, 0) = Number of bytes in environment identifier string + * TOS(st, 1) = Address environment identifier string + * ON RETURN (above replaced with): + * TOS(st, 0) = MS 16-bits of 32-bit C string pointer + * TOS(st, 1) = LS 16-bits of 32-bit C string pointer + */ + + case lbGETENV : + len = TOS(st, 0); /* Number of bytes in string */ + src = (uint8_t*)&GETSTACK(st, TOS(st, 1)); /* Pointer to string */ + + /* Make a C string out of the pascal string */ + + name = pexec_mkcstring(src, len); + if (name == NULL) + { + return eNOMEMORY; + } + + /* Make the C-library call and free the string copy */ + + src = (uint8_t*)getenv((char*)name); + free_cstring(name); + + /* Save the returned pointer in the stack */ + + TOS(st, 0) = (ustack_t)((uint32_t)src >> 16); + TOS(st, 1) = (ustack_t)((uint32_t)src & 0x0000ffff); + break; + + /* Copy pascal string to a pascal string + * + * ON INPUT: + * TOS(st, 0) = address of dest string hdr + * TOS(st, 1) = length of source string + * TOS(st, 2) = pointer to source string + * ON RETURN (input consumed): + */ + + case lbSTR2STR : + /* "Pop" in the input parameters from the stack */ + + POP(st, addr1); /* addr of dest string header */ + POP(st, uparm1); /* length of source data */ + POP(st, addr2); /* addr of source string data */ + + /* Do nothing if the source and destinations are the same + * string. This happens normally on cases like: + * string name; + * char c; + * name := name + c; + */ + + if (addr1 != addr2) + { + /* The source and destination strings are different. + * Make sure that the string length will fit into the destination. + */ + + if (uparm1 >= sSTRING_MAX_SIZE) + { + /* Clip to the maximum size */ + + uparm1 = sSTRING_MAX_SIZE; + len = sSTRING_MAX_SIZE; + } + else + { + /* We have space */ + + len = (int)uparm1; + } + + /* Get proper string pointers */ + + dest = ATSTACK(st, addr1); + src = ATSTACK(st, addr2); + + /* Transfer the (16-bit) string length (must be aligned!) */ + + tmp = (uint16_t*)dest; + *tmp++ = uparm1; + dest = (uint8_t*)tmp; + + /* Then transfer the string contents */ + + memcpy(dest, src, len); + } + break; + + /* Copy C string to a pascal string + * + * ON INPUT: + * TOS(st, 0) = address of dest hdr + * TOS(st, 1) = MS 16-bits of 32-bit C string pointer + * TOS(st, 2) = LS 16-bits of 32-bit C string pointer + * ON RETURN (input consumed): + */ + case lbCSTR2STR : + /* "Pop" in the input parameters from the stack */ + + POP(st, addr1); /* addr of dest string header */ + POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */ + POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */ + + /* Get proper string pointers */ + + dest = ATSTACK(st, addr1); + src = (uint8_t*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2); + + /* Handle null src pointer */ + + if (src == NULL) + { + *dest = 0; + } + else + { + /* Get the length of the string */ + + uparm1 = strlen((char*)src); + + /* Make sure that the string length will fit into the + * destination. */ + + if (uparm1 >= sSTRING_MAX_SIZE) + { + /* Clip to the maximum size */ + + uparm1 = sSTRING_MAX_SIZE; + len = sSTRING_MAX_SIZE; + } + else + { + /* We have space */ + + len = (int)uparm1; + } + + /* Transfer the (16-bit) string length (must be aligned!) */ + + tmp = (uint16_t*)dest; + *tmp++ = uparm1; + dest = (uint8_t*)tmp; + + /* Then transfer the string contents */ + + memcpy(dest, src, len); + } + break; + + /* Copy pascal string to a pascal string reference + * procedure str2rstr(src : string; var dest : rstring) + * ON INPUT: + * TOS(st, 0)=address of dest string reference + * TOS(st, 1)=length of source string + * TOS(st, 2)=pointer to source string + * ON RETURN: actual parameters released. + */ + + case lbSTR2RSTR : + /* "Pop" in the input parameters from the stack */ + + POP(st, addr1); /* addr of dest string reference */ + POP(st, uparm1); /* length of source data */ + POP(st, addr2); /* addr of source string data */ + + /* Make sure that the string length will fit into the destination. */ + + if (uparm1 >= sSTRING_MAX_SIZE) + { + return eSTRSTKOVERFLOW; + } + + /* Get a pointer to the destination reference */ + + ref = (uint16_t*)ATSTACK(st, addr1); + + /* Get proper string pointers */ + + dest = ATSTACK(st, ref[0] - 2); + src = ATSTACK(st, addr2); + + /* Transfer the (16-bit) string length (must be aligned!) */ + + tmp = (uint16_t*)dest; + *tmp++ = uparm1; + dest = (uint8_t*)tmp; + + /* Then transfer the string contents and save the new size */ + + memcpy(dest, src, uparm1); + ref[1] = uparm1; + break; + + /* Copy C string to a pascal string reference + * procedure cstr2str(src : cstring; var dest : string) + * ON INPUT: + * TOS(st, 0)=address of dest string reference + * TOS(st, 0)=MS 16-bits of 32-bit C source string pointer + * TOS(st, 1)=LS 16-bits of 32-bit C source string pointer + * ON RETURN: actual parameters released + */ + + case lbCSTR2RSTR : + /* "Pop" in the input parameters from the stack */ + + POP(st, addr1); /* addr of dest string reference */ + POP(st, uparm1); /* MS 16-bits of 32-bit C string pointer */ + POP(st, uparm2); /* LS 16-bits of 32-bit C string pointer */ + + /* Get a pointer to the destination reference */ + + ref = (uint16_t*)ATSTACK(st, addr1); + + /* Get proper string pointers */ + + dest = ATSTACK(st, ref[0] - 2); + src = (uint8_t*)((unsigned long)uparm1 << 16 | (unsigned long)uparm2); + + /* Handle null src pointer */ + + if (src == NULL) + { + *dest = 0; + } + else + { + /* Get the length of the string */ + + uparm1 = strlen((char*)src); + + /* Make sure that the string length will fit into the + * destination. */ + + if (uparm1 >= sSTRING_MAX_SIZE) + { + return eSTRSTKOVERFLOW; + } + + /* Transfer the (16-bit) string length (must be aligned!) */ + + tmp = (uint16_t*)dest; + *tmp++ = uparm1; + dest = (uint8_t*)tmp; + + /* Then transfer the string contents */ + + memcpy(dest, src, uparm1); + ref[1] = uparm1; + } + break; + + /* Convert a string to a numeric value + * procedure val(const s : string; var v; var code : word); + * + * Description: + * val() converts the value represented in the string S to a numerical + * value, and stores this value in the variable V, which can be of type + * Longint, Real and Byte. If the conversion isn't succesfull, then the + * parameter Code contains the index of the character in S which + * prevented the conversion. The string S is allowed to contain spaces + * in the beginning. + * + * The string S can contain a number in decimal, hexadecimal, binary or + * octal format, as described in the language reference. + * + * Errors: + * If the conversion doesn¡Çt succeed, the value of Code indicates the + * position where the conversion went wrong. + * + * ON INPUT + * TOS(st, 0)=address of code + * TOS(st, 1)=address of value + * TOS(st, 2)=length of source string + * TOS(st, 3)=pointer to source string + * ON RETURN: actual parameters released + */ + + case lbVAL : + /* Get the string information */ + + len = TOS(st, 2); /* Number of bytes in string */ + src = (uint8_t*)&GETSTACK(st, TOS(st, 3)); /* Pointer to string */ + + /* Make a C string out of the pascal string */ + + name = pexec_mkcstring(src, len); + if (name == NULL) + { + return eNOMEMORY; + } + + /* Convert the string to an integer */ + + value = atoi((char*)name); + if ((value < MININT) || (value > MAXINT)) + { + return eINTEGEROVERFLOW; + } + PUTSTACK(st, TOS(st, 0), 0); + PUTSTACK(st, TOS(st, 1), value); + DISCARD(st, 4); + break; + + /* Create an empty string + * function mkstk : string; + * ON INPUT + * ON RETURN + * TOS(st, 0)=length of new string + * TOS(st, 1)=pointer to new string + */ + + case lbMKSTK : + /* Allocate space on the string stack for the new string + * FIXME: This logic does not handle strings with other than the + * default size! + */ + + addr1 = ((st->csp + 1) & ~1); + st->csp += sSTRING_SIZE; /* Allocate max size */ + + /* Save the length at the beginning of the copy */ + + tmp = (uint16_t*)&GETSTACK(st, addr1); /* Pointer to new string */ + *tmp++ = 0; /* Save current size */ + + /* Update the stack content */ + + PUSH(st, addr1 + sSTRING_HDR_SIZE); /* Pointer to new string */ + PUSH(st, 0); /* Current size */ + break; + + /* Replace a string with a duplicate string residing in allocated + * string stack. + * function mkstkstr(name : string) : string; + * ON INPUT + * TOS(st, 0)=length of original string + * TOS(st, 1)=pointer to original string data + * ON RETURN + * TOS(st, 0)=length of new string (unchanged) + * TOS(st, 1)=pointer to new string data + */ + + case lbMKSTKSTR : + /* Get the parameters from the stack (leaving the string reference + * in place. + */ + + uparm1 = TOS(st, 0); /* Original string size */ + addr1 = TOS(st, 1); /* Original string data pointer */ + + /* Check if there is space on the string stack for the new string + * FIXME: This logic does not handle strings with other than the + * default size! + */ + + if (st->csp + sSTRING_SIZE >= st->spb) + { + return eSTRSTKOVERFLOW; + } + + /* Allocate space on the string stack for the new string */ + + addr2 = ((st->csp + 1) & ~1); + st->csp += sSTRING_SIZE; /* Allocate max size */ + + /* Save the length at the beginning of the copy */ + + tmp = (uint16_t*)&GETSTACK(st, addr2); /* Pointer to new string */ + *tmp++ = uparm1; /* Save current size */ + dest = (uint8_t*)tmp; /* Pointer to string data */ + + /* Copy the string into the string stack */ + + src = (uint8_t*)&GETSTACK(st, addr1); /* Pointer to original string */ + memcpy(dest, src, uparm1); + + /* Update the stack content */ + + TOS(st, 1) = addr2 + sSTRING_HDR_SIZE; + break; + + /* Replace a character with a string residing in allocated string stack. + * function mkstkc(c : char) : string; + * ON INPUT + * TOS(st, 0)=Character value + * ON RETURN + * TOS(st, 0)=length of new string + * TOS(st, 1)=pointer to new string + */ + + case lbMKSTKC : + /* Check if there is space on the string stack for the new string + * FIXME: This logic does not handle strings with other than the + * default size! + */ + + if (st->csp + sSTRING_SIZE >= st->spb) + { + return eSTRSTKOVERFLOW; + } + + /* Allocate space on the string stack for the new string */ + + addr2 = ((st->csp + 1) & ~1); + st->csp += sSTRING_SIZE; /* Allocate max size */ + + /* Save the length at the beginning of the copy */ + + tmp = (uint16_t*)&GETSTACK(st, addr2); /* Pointer to new string */ + *tmp++ = 1; /* Save initial size */ + dest = (uint8_t*)tmp; /* Pointer to string data */ + + /* Copy the character into the string stack */ + + *dest++ = TOS(st, 0); /* Save character as string */ + + /* Update the stack content */ + + TOS(st, 0) = addr2 + sSTRING_HDR_SIZE; /* String address */ + PUSH(st, 1); /* String length */ + break; + + /* Concatenate a string to the end of a string. + * function strcat(name : string, c : char) : string; + * + * ON INPUT + * TOS(st, 0)=length of string1 + * TOS(st, 1)=pointer to string1 data + * TOS(st, 2)=length of string2 + * TOS(st, 3)=pointer to string2 data + * ON OUTPUT + * TOS(st, 1)=new length of string2 + * TOS(st, 2)=pointer to string2 + */ + + case lbSTRCAT : + /* Get the parameters from the stack (leaving the string reference + * in place. + */ + + POP(st, uparm1); /* string1 size */ + POP(st, addr1); /* string1 data stack addr */ + uparm2 = TOS(st, 0); /* string2 size */ + + /* Check for string overflow. FIXME: This logic does not handle + * strings with other than the default size! + */ + + if (uparm1 + uparm2 > sSTRING_MAX_SIZE) + return eSTRSTKOVERFLOW; + else + { + /* Get a pointer to string1 data */ + + src = ATSTACK(st, addr1); + + /* Get a pointer to string2 header, set new size then, get + * a pointer to string2 data. + */ + + tmp = ((uint16_t*)&GETSTACK(st, TOS(st, 1))) - 1; + *tmp++ = uparm1 + uparm2; + dest = (uint8_t*)tmp; + + memcpy(&dest[uparm2], src, uparm1); /* cat strings */ + TOS(st, 0) = uparm1 + uparm2; /* Save new size */ + } + break; + + /* Concatenate a character to the end of a string. + * function strcatc(name : string, c : char) : string; + * + * ON INPUT + * TOS(st, 0)=character to concatenate + * TOS(st, 1)=length of string + * TOS(st, 2)=pointer to string + * ON OUTPUT + * TOS(st, 1)=new length of string + * TOS(st, 2)=pointer to string + */ + + case lbSTRCATC : + /* Get the parameters from the stack (leaving the string reference + * in place. + */ + + POP(st, uparm1); /* Character to concatenate */ + uparm2 = TOS(st, 0); /* Current length of string */ + + /* Check for string overflow. FIXME: This logic does not handle + * strings with other than the default size! + */ + + if (uparm2 >= sSTRING_MAX_SIZE) + return eSTRSTKOVERFLOW; + else + { + /* Get a pointer to string header, set size new size then, get + * a pointer to string data. + */ + + tmp = ((uint16_t*)&GETSTACK(st, TOS(st, 1))) - 1; + *tmp++ = uparm2 + 1; + dest = (uint8_t*)tmp; + + /* Add the new charcter */ + + dest[uparm2] = (uint8_t)uparm1; + + /* Save the new string size */ + + TOS(st, 0) = uparm2 + 1; + } + break; + + /* Compare two pascal strings + * function strcmp(name1 : string, name2 : string) : integer; + * ON INPUT + * TOS(st, 1)=length of string2 + * TOS(st, 2)=address of string2 data + * TOS(st, 3)=length of string1 + * TOS(st, 4)=address of string1 data + * ON OUTPUT + * TOS(st, 0)=(-1=less than, 0=equal, 1=greater than} + */ + + case lbSTRCMP : + { + int result; + + /* Get the parameters from the stack (leaving space for the + * return value); + */ + + POP(st, uparm2); /* length of string2 */ + POP(st, addr2); /* address of string2 data */ + POP(st, uparm1); /* length of string1 */ + addr1 = TOS(st, 0); /* address of string1 data */ + + /* Get full address */ + + dest = ATSTACK(st, addr1); + src = ATSTACK(st, addr2); + + /* If name1 is shorter than name2, then we can only return + * -1 (less than) or +1 greater than. If the substrings + * of length of name1 are equal, then we return less than. + */ + + if (uparm1 < uparm2) + { + result = memcmp(dest, src, uparm1); + if (result == 0) result = -1; + } + + /* If name1 is longer than name2, then we can only return + * -1 (less than) or +1 greater than. If the substrings + * of length of name2 are equal, then we return greater than. + */ + + else if (uparm1 > uparm2) + { + result = memcmp(dest, src, uparm2); + if (result == 0) result = 1; + } + + /* The strings are of equal length. Return the result of + * the comparison. + */ + + else + { + result = memcmp(dest, src, uparm1); + } + TOS(st, 0) = result; + } + break; + + default : + return eBADSYSLIBCALL; + + } + + return eNOERROR; + +} /* end pexec_libcall */ + +/**************************************************************************** + * Name: pexec_execfp + * + * Description: + * This function processes a floating point operation. + * + ****************************************************************************/ + +static uint16_t pexec_execfp(struct pexec_s *st, uint8_t fpop) +{ + int16_t intValue; + fparg_t arg1; + fparg_t arg2; + fparg_t result; + + switch (fpop & fpMASK) + { + /* Floating Pointer Conversions (On stack argument: FP or Integer) */ + + case fpFLOAT : + POP(st, intValue); + result.f = (double)intValue; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + + case fpTRUNC : + case fpROUND : + pexec_getfparguments(st, fpop, &arg1, NULL); + intValue = (int16_t)arg1.f; + PUSH(st, intValue); + break; + + /* Floating Point arithmetic instructions (Two FP stack arguments) */ + + case fpADD : + pexec_getfparguments(st, fpop, &arg1, &arg2); + result.f = arg1.f + arg2.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpSUB : + pexec_getfparguments(st, fpop, &arg1, &arg2); + result.f = arg1.f - arg2.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpMUL : + pexec_getfparguments(st, fpop, &arg1, &arg2); + result.f = arg1.f * arg2.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpDIV : + pexec_getfparguments(st, fpop, &arg1, &arg2); + result.f = arg1.f / arg2.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpMOD : + return eBADFPOPCODE; +#if 0 /* Not yet */ + pexec_getfparguments(st, fpop, &arg1, &arg2); + result.f = arg1.f % arg2.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; +#endif + + /* Floating Point Comparisons (Two FP stack arguments) */ + + case fpEQU : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f == arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + case fpNEQ : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f != arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + case fpLT : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f < arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + case fpGTE : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f >= arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + case fpGT : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f > arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + case fpLTE : + pexec_getfparguments(st, fpop, &arg1, &arg2); + intValue = PFALSE; + if (arg1.f <= arg2.f) + intValue = PTRUE; + PUSH(st, intValue); + break; + + /* Floating Point arithmetic instructions (One FP stack arguments) */ + + case fpNEG : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = -arg1.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; +#ifdef CONFIG_HAVE_LIBM + case fpABS : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = fabs(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; +#endif + case fpSQR : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = arg1.f * arg1.f; + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; +#ifdef CONFIG_HAVE_LIBM + case fpSQRT : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = sqrt(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpSIN : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = sin(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpCOS : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = cos(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpATAN : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = atan(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpLN : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = log(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; + case fpEXP : + pexec_getfparguments(st, fpop, &arg1, NULL); + result.f = exp(arg1.f); + PUSH(st, result.hw[0]); + PUSH(st, result.hw[1]); + PUSH(st, result.hw[2]); + PUSH(st, result.hw[3]); + break; +#endif + + default : + return eBADFPOPCODE; + + } + return eNOERROR; + +} /* end pexec_execfp */ + +/**************************************************************************** + * Name: pexec_getfparguments + * + * Description: + * This function retrieves the floating point arguments and performs + * integer to REAL conversions as necessary + * + ****************************************************************************/ + +static void pexec_getfparguments(struct pexec_s *st, uint8_t fpop, fparg_t *arg1, fparg_t *arg2) +{ + int16_t sparm; + + /* Extract arg2 from the stack */ + + if (arg2) + { + /* Convert an integer argument to type REAL */ + + if ((fpop & fpARG2) != 0) + { + POP(st, sparm); + arg2->f = (double)sparm; + } + else + { + POP(st, arg2->hw[3]); + POP(st, arg2->hw[2]); + POP(st, arg2->hw[1]); + POP(st, arg2->hw[0]); + } + } + + /* Extract arg1 from the stack */ + + if (arg1) + { + /* Convert an integer argument to type REAL */ + + if ((fpop & fpARG1) != 0) + { + POP(st, sparm); + arg1->f = (double)sparm; + } + else + { + POP(st, arg1->hw[3]); + POP(st, arg1->hw[2]); + POP(st, arg1->hw[1]); + POP(st, arg1->hw[0]); + } + } + +} /* end pexec_getfparguments */ + +/**************************************************************************** + * Name: pexec_readinteger + * + * Description: + * This function parses a decimal integer from ioptr + ****************************************************************************/ + +static ustack_t pexec_readinteger(uint8_t *ioptr) +{ + sstack_t value = 0; + + while (isspace(*ioptr)) ioptr++; + while ((*ioptr >= '0') && (*ioptr <= '9')) + { + value = 10*value + + (sstack_t)(*ioptr) + - (sstack_t)'0'; + ioptr++; + } + + return (ustack_t)value; + +} /* end pexec_readinteger */ + +/**************************************************************************** + * Name: pexec_readreal + * + * Description: + * This function parses a decimal integer from ioptr. + * + ****************************************************************************/ + +static void pexec_readreal(uint16_t *dest, uint8_t *inPtr) +{ + int32_t intpart; + fparg_t result; + double fraction; + uint8_t unaryop; + + intpart = 0; + unaryop = '+'; + + /* Check for a leading unary - */ + + if ((*inPtr == '-') || (*inPtr == '+')) + unaryop = *inPtr++; + + /* Get the integer part of the real */ + + while ((*inPtr >= '0') && (*inPtr <= '9')) + intpart = 10*intpart + ((int32_t)*inPtr++) - ((int32_t)'0'); + + result.f = ((double)intpart); + + /* Check for the a fractional part */ + + if (*inPtr == '.') + { + inPtr++; + fraction = 0.1; + while ((*inPtr >= '0') && (*inPtr <= '9')) + { + result.f += fraction * (double)(((int32_t)*inPtr++) - ((int32_t)'0')); + fraction /= 10.0; + } + } + + /* Correct the sign of the result */ + + if (unaryop == '-') + result.f = -result.f; + + /* Return the value into the P-Machine stack */ + + *dest++ = result.hw[0]; + *dest++ = result.hw[1]; + *dest++ = result.hw[2]; + *dest = result.hw[3]; + +} /* end pexec_readreal */ + +/**************************************************************************** + * Name: pexec_getbaseaddress + * + * Description: + * This function binds the base address corresponding to a given level + * offset. + * + ****************************************************************************/ + +static ustack_t pexec_getbaseaddress(struct pexec_s *st, level_t leveloffset) +{ + /* Start with the base register of the current frame */ + + ustack_t baseAddress = st->fp; + + /* Search backware "leveloffset" frames until the correct frame is + * found + */ + + while (leveloffset > 0) + { + baseAddress = st->dstack.i[BTOISTACK(baseAddress)]; + leveloffset--; + } + + /* Offset that value by two words (one for the st->fp and one for the + * return value + */ + + return baseAddress + 2*BPERI; + +} /* end pexec_getbaseaddress */ + +/**************************************************************************** + * Name: pexec_mkcstring + ****************************************************************************/ + +static uint8_t *pexec_mkcstring(uint8_t *buffer, int buflen) +{ + uint8_t *string; + + string = malloc(buflen + 1); + if (string != NULL) + { + memcpy(string, buffer, buflen); + string[buflen] = '\0'; + } + return string; +} + +/**************************************************************************** + * Name: pexec8 + * + * Descripton: + * Handle 8-bit instructions with no immediate data + * + ****************************************************************************/ + +static inline int pexec8(FAR struct pexec_s *st, uint8_t opcode) +{ + sstack_t sparm; + ustack_t uparm1; + ustack_t uparm2; + ustack_t uparm3; + + switch (opcode) + { + /* Arithmetic & logical & and integer conversions (One stack argument) */ + case oNEG : + TOS(st, 0) = (ustack_t)(-(sstack_t)TOS(st, 0)); + break; + case oABS : + if (signExtend16(TOS(st, 0)) < 0) + { + TOS(st, 0) = (ustack_t)(-signExtend16(TOS(st, 0))); + } + break; + case oINC : + TOS(st, 0)++; + break; + case oDEC : + TOS(st, 0)--; + break; + case oNOT : + TOS(st, 0) = ~TOS(st, 0); + break; + + /* Arithmetic & logical (Two stack arguments) */ + + case oADD : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) + sparm); + break; + case oSUB : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) - sparm); + break; + case oMUL : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) * sparm); + break; + case oDIV : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) / sparm); + break; + case oMOD : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) % sparm); + break; + case oSLL : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) << sparm); + break; + case oSRL : + POP(st, sparm); + TOS(st, 0) = (TOS(st, 0) >> sparm); + break; + case oSRA : + POP(st, sparm); + TOS(st, 0) = (ustack_t)(((sstack_t)TOS(st, 0)) >> sparm); + break; + case oOR : + POP(st, uparm1); + TOS(st, 0) = (TOS(st, 0) | uparm1); + break; + case oAND : + POP(st, uparm1); + TOS(st, 0) = (TOS(st, 0) & uparm1); + break; + case oBIT : + POP(st, uparm1); + uparm2 = TOS(st, 0); + if ((uparm1 & (1 << uparm2)) != 0) + { + TOS(st, 0) = PTRUE; + } + else + { + TOS(st, 0) = PFALSE; + } + break; + + /* Comparisons (One stack argument) */ + + case oEQUZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm == 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + case oNEQZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm != 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + case oLTZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm < 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + case oGTEZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm >= 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + case oGTZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm > 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + case oLTEZ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm <= 0) + { + uparm1 = PTRUE; + } + PUSH(st, uparm1); + break; + + /* Comparisons (Two stack arguments) */ + + case oEQU : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm == (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + case oNEQ : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm != (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + case oLT : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm < (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + case oGTE : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm >= (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + case oGT : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm > (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + case oLTE : + POP(st, sparm); + uparm1 = PFALSE; + if (sparm <= (sstack_t)TOS(st, 0)) + { + uparm1 = PTRUE; + } + TOS(st, 0) = uparm1; + break; + + /* Load (One stack argument) */ + + case oLDI : + POP(st, uparm1); /* Address */ + PUSH(st, GETSTACK(st, uparm1)); + PUSH(st, GETSTACK(st, uparm1 + BPERI)); + break; + case oLDIH : + TOS(st, 0) = GETSTACK(st, TOS(st, 0)); + break; + case oLDIB : + TOS(st, 0) = GETBSTACK(st, TOS(st, 0)); + break; + case oLDIM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size */ + POP(st, uparm2); /* Stack offset */ + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUSH(st, GETSTACK(st, uparm2)); + uparm2 += BPERI; + uparm1 -= BPERI; + } + else + { + PUSH(st, GETBSTACK(st, uparm2)); + uparm2++; + uparm1--; + } + } + break; + case oDUP : + uparm1 = TOS(st, 0); + uparm2 = TOS(st, 1); + PUSH(st, uparm2); + PUSH(st, uparm1); + break; + case oDUPH : + uparm1 = TOS(st, 0); + PUSH(st, uparm1); + break; + case oPUSHS : + PUSH(st, st->csp); + break; + case oPOPS : + POP(st, st->csp); + break; + + /* Store (Two stack arguments) */ + + case oSTIH : + POP(st, uparm1); + POP(st, uparm2); + PUTSTACK(st, uparm1,uparm2); + break; + case oSTIB : + POP(st, uparm1); + POP(st, uparm2); + PUTBSTACK(st, uparm1, uparm2); + break; + case oSTIM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size in bytes */ + uparm3 = uparm1; /* Save for stack discard */ + sparm = ROUNDBTOI(uparm1); /* Size in words */ + uparm2 = TOS(st, sparm); /* Stack offset */ + sparm--; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUTSTACK(st, TOS(st, sparm), uparm2); + uparm2 += BPERI; + uparm1 -= BPERI; + sparm--; + } + else + { + PUTBSTACK(st, TOS(st, sparm), uparm2); + uparm2++; + uparm1--; + } + } + + /* Discard the stored data + the stack offset */ + + DISCARD(st, (ROUNDBTOI(uparm3) + 1)); + break; + + /* Program control (No stack arguments) */ + + case oNOP : + break; + case oRET : + POP(st, st->pc); + POP(st, st->fp); + DISCARD(st, 1); + return eNOERROR; + + /* System Functions (No stack arguments) */ + + case oEND : + return eEXIT; + + default : + return eILLEGALOPCODE; + } + + st->pc += 1; + return eNOERROR; +} + +/**************************************************************************** + * Name: pexec16 + * + * Descripton: + * Handle 16-bit instructions with 8-bits of immediate data (imm8) + * + ****************************************************************************/ + +static inline int pexec16(FAR struct pexec_s *st, uint8_t opcode, uint8_t imm8) +{ + int ret = eNOERROR; + + st->pc += 2; + switch (opcode) + { + /* Data stack: imm8 = 8 bit unsigned data (no stack arguments) */ + + case oPUSHB : + PUSH(st, imm8); + break; + + /* Floating Point: imm8 = FP op-code (varying number of stack arguments) */ + case oFLOAT : + ret = pexec_execfp(st, imm8); + break; + + default : + ret = eILLEGALOPCODE; + break; + } + return ret; +} + +/**************************************************************************** + * Name: pexec24 + * + * Descripton: + * Handle 24-bit instructions with 16-bits of immediate data (imm16) + * + ****************************************************************************/ + +static inline int pexec24(FAR struct pexec_s *st, uint8_t opcode, uint16_t imm16) +{ + sstack_t sparm1; + sstack_t sparm2; + ustack_t uparm1; + ustack_t uparm2; + ustack_t uparm3; + int ret = eNOERROR; + + switch (opcode) + { + /* Program control: imm16 = unsigned label (no stack arguments) */ + + case oJMP : + goto branch_out; + + /* Program control: imm16 = unsigned label (One stack argument) */ + + case oJEQUZ : + POP(st, sparm1); + if (sparm1 == 0) + { + goto branch_out; + } + break; + case oJNEQZ : + POP(st, sparm1); + if (sparm1 != 0) + { + goto branch_out; + } + break; + case oJLTZ : + POP(st, sparm1); + if (sparm1 < 0) + { + goto branch_out; + } + break; + case oJGTEZ : + POP(st, sparm1); + if (sparm1 >= 0) + { + goto branch_out; + } + break; + case oJGTZ : + POP(st, sparm1); + if (sparm1 > 0) + { + goto branch_out; + } + break; + case oJLTEZ : + POP(st, sparm1); + if (sparm1 <= 0) + { + goto branch_out; + } + break; + + /* Program control: imm16 = unsigned label (Two stack arguments) */ + + case oJEQU : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 == sparm1) + { + goto branch_out; + } + break; + case oJNEQ : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 != sparm1) + { + goto branch_out; + } + break; + case oJLT : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 < sparm1) + { + goto branch_out; + } + break; + case oJGTE : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 >= sparm1) + { + goto branch_out; + } + break; + case oJGT : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 > sparm1) + { + goto branch_out; + } + break; + case oJLTE : + POP(st, sparm1); + POP(st, sparm2); + if (sparm2 <= sparm1) + { + goto branch_out; + } + break; + + /* Load: imm16 = usigned offset (no stack arguments) */ + + case oLD : + uparm1 = st->spb + imm16; + PUSH(st, GETSTACK(st, uparm1)); + PUSH(st, GETSTACK(st, uparm1 + BPERI)); + break; + case oLDH : + uparm1 = st->spb + imm16; + PUSH(st, GETSTACK(st, uparm1)); + break; + case oLDB : + uparm1 = st->spb + imm16; + PUSH(st, GETBSTACK(st, uparm1)); + break; + case oLDM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); + uparm2 = st->spb + imm16; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUSH(st, GETSTACK(st, uparm2)); + uparm2 += BPERI; + uparm1 -= BPERI; + } + else + { + PUSH(st, GETBSTACK(st, uparm2)); + uparm2++; + uparm1--; + } + } + break; + + /* Load & store: imm16 = unsigned base offset (One stack argument) */ + + case oST : + uparm1 = st->spb + imm16; + POP(st, uparm2); + PUTSTACK(st, uparm2, uparm1 + BPERI); + POP(st, uparm2); + PUTSTACK(st, uparm2, uparm1); + break; + case oSTH : + uparm1 = st->spb + imm16; + POP(st, uparm2); + PUTSTACK(st, uparm2, uparm1); + break; + case oSTB : + uparm1 = st->spb + imm16; + POP(st, uparm2); + PUTBSTACK(st, uparm2, uparm1); + break; + case oSTM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size */ + uparm3 = uparm1; /* Save for stack discard */ + uparm2 = st->spb + imm16; + sparm1 = ROUNDBTOI(uparm1) - 1; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUTSTACK(st, TOS(st, sparm1), uparm2); + uparm2 += BPERI; + uparm1 -= BPERI; + sparm1--; + } + else + { + PUTBSTACK(st, TOS(st, sparm1), uparm2); + uparm2++; + uparm1--; + } + } + + /* Discard the stored data */ + + DISCARD(st, ROUNDBTOI(uparm3)); + break; + case oLDX : + uparm1 = st->spb + imm16 + TOS(st, 0); + TOS(st, 0) = GETSTACK(st, uparm1); + PUSH(st, GETSTACK(st, uparm1 + BPERI)); + break; + case oLDXH : + uparm1 = st->spb + imm16 + TOS(st, 0); + TOS(st, 0) = GETSTACK(st, uparm1); + break; + case oLDXB : + uparm1 = st->spb + imm16 + TOS(st, 0); + TOS(st, 0) = GETBSTACK(st, uparm1); + break; + case oLDXM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); + POP(st, uparm2); + uparm2 += st->spb + imm16; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUSH(st, GETSTACK(st, uparm2)); + uparm2 += BPERI; + uparm1 -= BPERI; + } + else + { + PUSH(st, GETBSTACK(st, uparm2)); + uparm2++; + uparm1--; + } + } + break; + + /* Store: imm16 = unsigned base offset (Two stack arguments) */ + + case oSTXH : + POP(st, uparm1); + POP(st, uparm2); + uparm2 += st->spb + imm16; + PUTSTACK(st, uparm1,uparm2); + break; + case oSTXB : + POP(st, uparm1); + POP(st, uparm2); + uparm2 += st->spb + imm16; + PUTBSTACK(st, uparm1, uparm2); + break; + case oSTXM : +/* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size */ + uparm3 = uparm1; /* Save for stack discard */ + sparm1 = ROUNDBTOI(uparm1); /* Size in 16-bit words */ + uparm2 = TOS(st, sparm1); /* index */ + sparm1--; + uparm2 += st->spb + imm16; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUTSTACK(st, TOS(st, sparm1), uparm2); + uparm2 += BPERI; + uparm1 -= BPERI; + sparm1--; + } + else + { + PUTBSTACK(st, TOS(st, sparm1), uparm2); + uparm2++; + uparm1--; + } + } + + /* Discard the stored data + the index */ + + DISCARD(st, (ROUNDBTOI(uparm3) + 1)); + break; + + case oLA : + uparm1 = st->spb + imm16; + PUSH(st, uparm1); + break; + case oLAX : + TOS(st, 0) = st->spb + imm16 + TOS(st, 0); + break; + + /* Data stack: imm16 = 16 bit signed data (no stack arguments) */ + + case oPUSH : + PUSH(st, imm16); + break; + case oINDS : + st->sp += signExtend16(imm16); + break; + + /* System Functions: + * For LIB: imm16 = sub-function code + */ + + case oLIB : + ret = pexec_libcall(st, imm16); + break; + + /* Program control: imm16 = unsigned label (no stack arguments) */ + + case oLAC : + uparm1 = imm16 + st->rop; + PUSH(st, uparm1); + break; + + case oLABEL : + default: + ret = eILLEGALOPCODE; + break; + } + + st->pc += 3; + return ret; + +branch_out: + st->pc = (addr_t)imm16; + return ret; +} + +/**************************************************************************** + * Name: pexec32 + * + * Descripton: + * Handle 32-bit instructions with 24-bits of immediate data (imm8+imm16) + * + ****************************************************************************/ + +static int pexec32(FAR struct pexec_s *st, uint8_t opcode, uint8_t imm8, uint16_t imm16) +{ + sstack_t sparm; + ustack_t uparm1; + ustack_t uparm2; + ustack_t uparm3; + int ret = eNOERROR; + + switch (opcode) + { + /* Load: imm8 = level; imm16 = signed frame offset (no stack arguments) */ + case oLDS : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUSH(st, GETSTACK(st, uparm1)); + PUSH(st, GETSTACK(st, uparm1 + BPERI)); + break; + case oLDSH : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUSH(st, GETSTACK(st, uparm1)); + break; + case oLDSB : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUSH(st, GETBSTACK(st, uparm1)); + break; + case oLDSM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); + uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUSH(st, GETSTACK(st, uparm2)); + uparm2 += BPERI; + uparm1 -= BPERI; + } + else + { + PUSH(st, GETBSTACK(st, uparm2)); + uparm2++; + uparm1--; + } + } + break; + + /* Load & store: imm8 = level; imm16 = signed frame offset (One stack argument) */ + + case oSTSH : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + POP(st, uparm2); + PUTSTACK(st, uparm2, uparm1); + break; + case oSTSB : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + POP(st, uparm2); + PUTBSTACK(st, uparm2, uparm1); + break; + case oSTSM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size */ + uparm3 = uparm1; /* Save for stack discard */ + uparm2 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + sparm = ROUNDBTOI(uparm1) - 1; + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUTSTACK(st, TOS(st, sparm), uparm2); + uparm2 += BPERI; + uparm1 -= BPERI; + sparm--; + } + else + { + PUTBSTACK(st, TOS(st, sparm), uparm2); + uparm2++; + uparm1--; + } + } + + /* Discard the stored data */ + + DISCARD(st, ROUNDBTOI(uparm3)); + break; + case oLDSX : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); + TOS(st, 0) = GETSTACK(st, uparm1); + PUSH(st, GETSTACK(st, uparm1 + BPERI)); + break; + case oLDSXH : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); + TOS(st, 0) = GETSTACK(st, uparm1); + break; + case oLDSXB : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); + TOS(st, 0) = GETBSTACK(st, uparm1); + break; + case oLDSXM : + /* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); + POP(st, uparm2); + uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUSH(st, GETSTACK(st, uparm2)); + uparm2 += BPERI; + uparm1 -= BPERI; + } + else + { + PUSH(st, GETBSTACK(st, uparm2)); + uparm2++; + uparm1--; + } + } + break; + + /* Store: imm8 = level; imm16 = signed frame offset (Two stack arguments) */ + + case oSTSXH : + POP(st, uparm1); + POP(st, uparm2); + uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUTSTACK(st, uparm1,uparm2); + break; + case oSTSXB : + POP(st, uparm1); + POP(st, uparm2); + uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUTBSTACK(st, uparm1, uparm2); + break; + case oSTSXM : +/* FIX ME --> Need to handle the unaligned case */ + POP(st, uparm1); /* Size */ + uparm3 = uparm1; /* Save for stack discard */ + sparm = ROUNDBTOI(uparm1); /* Size in 16-bit words */ + uparm2 = TOS(st, sparm); /* index */ + sparm--; + uparm2 += pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + while (uparm1 > 0) + { + if (uparm1 >= BPERI) + { + PUTSTACK(st, TOS(st, sparm), uparm2); + uparm2 += BPERI; + uparm1 -= BPERI; + sparm--; + } + else + { + PUTBSTACK(st, TOS(st, sparm), uparm2); + uparm2++; + uparm1--; + } + } + + /* Discard the stored data + the index */ + + DISCARD(st, (ROUNDBTOI(uparm3) + 1)); + break; + + case oLAS : + uparm1 = pexec_getbaseaddress(st, imm8) + signExtend16(imm16); + PUSH(st, uparm1); + break; + case oLASX : + TOS(st, 0) = pexec_getbaseaddress(st, imm8) + signExtend16(imm16) + TOS(st, 0); + break; + + /* Program Control: imm8 = level; imm16 = unsigned label (No + * stack arguments) + */ + + case oPCAL : + PUSH(st, pexec_getbaseaddress(st, imm8)); + PUSH(st, st->fp); + uparm1 = st->sp; + PUSH(st, st->pc + 4); + st->fp = uparm1; + st->pc = (addr_t)imm16; + return eNOERROR; + + /* System Functions: + * For SYSIO: imm8 = file number; imm16 = sub-function code + */ + + case oSYSIO : + ret = pexec_sysio(st, imm8, imm16); + break; + + /* Psuedo-operations: (No stack arguments) + * For LINE: imm8 = file number; imm16 = line number + */ + + case oLINE : + default : + ret = eILLEGALOPCODE; + break; + } + + st->pc += 4; + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pexec_init + ****************************************************************************/ + +FAR struct pexec_s *pexec_init(struct pexec_attr_s *attr) +{ + struct pexec_s *st; + addr_t stacksize; + addr_t adjusted_rosize; + + /* Allocate the p-machine state stucture */ + + st = (struct pexec_s *)malloc(sizeof(struct pexec_s)); + if (!st) + { + return NULL; + } + + /* Set up I-Space */ + + st->ispace = attr->ispace; + st->maxpc = attr->maxpc; + + /* Align size of read-only data to 16-bit boundary. */ + + adjusted_rosize = (attr->rosize + 1) & ~1; + + /* Allocate the pascal stack. Organization is string stack, then + * constant data, then "normal" pascal stack. + */ + + stacksize = attr->varsize + adjusted_rosize + attr->strsize; + st->dstack.b = (uint8_t*)malloc(stacksize); + if (!st->dstack.b) + { + free(st); + return NULL; + } + + /* Copy the rodata into the stack */ + + if (attr->rodata && attr->rosize) + { + memcpy(&st->dstack.b[attr->strsize], attr->rodata, attr->rosize); + } + + /* Set up info needed to perform a simulated reset */ + + st->strsize = attr->strsize; + st->rosize = adjusted_rosize; + st->entry = attr->entry; + st->stacksize = stacksize; + + /* Then perform a simulated reset */ + + pexec_reset(st); + return st; +} + +/**************************************************************************** + * Name: pexec + ****************************************************************************/ + +int pexec(FAR struct pexec_s *st) +{ + uint8_t opcode; + int ret; + + /* Make sure that the program counter is within range */ + + if (st->pc >= st->maxpc) + { + ret = eBADPC; + } + else + { + /* Get the instruction to execute */ + + opcode = st->ispace[st->pc]; + if ((opcode & o8) != 0) + { + /* Get the immediate, 8-bit value */ + + uint8_t imm8 = st->ispace[st->pc + 1]; + if ((opcode & o16) != 0) + { + /* Get the immediate, big-endian 16-bit value */ + + uint16_t imm16 = ((st->ispace[st->pc + 2]) << 8) | st->ispace[st->pc + 3]; + + /* Handle 32 bit instructions */ + + ret = pexec32(st, opcode, imm8, imm16); + } + else + { + /* Handle 16-bit instructions */ + + ret = pexec16(st, opcode, imm8); + } + } + else if ((opcode & o16) != 0) + { + /* Get the immediate, big-endian 16-bit value */ + + uint16_t imm16 = ((st->ispace[st->pc + 1]) << 8) | st->ispace[st->pc + 2]; + + /* Handle 24-bit instructions */ + + ret = pexec24(st, opcode, imm16); + } + else + { + /* Handle 8-bit instructions */ + + ret = pexec8(st, opcode); + } + } + return ret; +} + +/**************************************************************************** + * Name: pexec_reset + ****************************************************************************/ + +void pexec_reset(struct pexec_s *st) +{ + int dndx; + + /* Setup the bottom of the "normal" pascal stack */ + + st->rop = st->strsize; + st->spb = st->strsize + st->rosize; + + /* Initialize the emulated P-Machine registers */ + + st->csp = 0; + st->sp = st->spb + 2*BPERI; + st->fp = st->spb + BPERI; + st->pc = st->entry; + + /* Initialize the P-Machine stack */ + + dndx = BTOISTACK(st->spb); + st->dstack.i[dndx] = 0; + st->dstack.i[dndx+1] = 0; + st->dstack.i[dndx+2] = -1; +} + +/**************************************************************************** + * Name: pexec_release + ****************************************************************************/ + +void pexec_release(struct pexec_s *st) +{ + if (st) + { + if (st->dstack.i) + { + free(st->dstack.i); + } + + if (st->ispace) + { + free(st->ispace); + } + + free(st); + } +} diff --git a/misc/pascal/insn16/prun/pload.c b/misc/pascal/insn16/prun/pload.c index f09c72063..8d5576019 100644 --- a/misc/pascal/insn16/prun/pload.c +++ b/misc/pascal/insn16/prun/pload.c @@ -1,175 +1,176 @@ -/**************************************************************************** - * pload.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -#include "keywords.h" -#include "pedefs.h" -#include "pofflib.h" -#include "perr.h" -#include "pexec.h" - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -FAR struct pexec_s *pload(const char *filename, addr_t varsize, addr_t strsize) -{ - struct pexec_attr_s attr; - struct pexec_s *st; - poffHandle_t phandle; - FILE *exe; - uint16 err; - ubyte ftype; - ubyte farch; - - /* Create a handle to contain the executable data */ - - phandle = poffCreateHandle(); - if (phandle == NULL) fatal(eNOMEMORY); - - /* Open the executable file */ - - if (!(exe = fopen(filename, "rb"))) - { - dbg("ERROR: Error opening '%s': %d\n", filename, errno); - goto errout_with_handle; - } - - /* Load the POFF file into memory */ - - err = poffReadFile(phandle, exe); - if (err != eNOERROR) - { - dbg("ERROR: Could not read %s: %d\n", filename, err); - goto errout_with_file; - } - - /* Verify that the file is a pascal executable */ - - ftype = poffGetFileType(phandle); - if (ftype != FHT_EXEC) - { - dbg("ERROR: File is not a pascal executable: %d\n", ftype); - goto errout_with_file; - } - - farch = poffGetArchitecture(phandle); - if (farch != FHA_PCODE_INSN16) - { - dbg("ERROR: File is not 16-bit pcode: %d\n", farch); - goto errout_with_file; - } - - /* Initialize the attribute structure */ - - attr.varsize = varsize; - attr.strsize = strsize; - - /* Extract the program entry point from the pascal executable */ - - attr.entry = poffGetEntryPoint(phandle); - - /* Close the POFF file */ - - (void)fclose(exe); - - /* Extract the program data from the POFF image */ - - attr.maxpc = poffExtractProgramData(phandle, &attr.ispace); - - /* Extract the read-only data from the POFF image */ - - attr.rosize = poffExtractRoData(phandle, &attr.rodata); - - /* Destroy the POFF image */ - - poffDestroyHandle(phandle); - - /* Initialize the p-code interpreter */ - - st = pexec_init(&attr); - if (!st && attr.ispace) - { - /* Initialization failed, discard the allocated I-Space */ - - free(st->ispace); - } - - /* Discard the allocated RO data in any event */ - - if (attr.rodata) - { - free(attr.rodata); - } - return st; - - errout_with_file: - (void)fclose(exe); - - errout_with_handle: - poffDestroyHandle(phandle); - return NULL; -} +/**************************************************************************** + * pload.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "keywords.h" +#include "pedefs.h" +#include "pofflib.h" +#include "perr.h" +#include "pexec.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +FAR struct pexec_s *pload(const char *filename, addr_t varsize, addr_t strsize) +{ + struct pexec_attr_s attr; + struct pexec_s *st; + poffHandle_t phandle; + FILE *exe; + uint16_t err; + uint8_t ftype; + uint8_t farch; + + /* Create a handle to contain the executable data */ + + phandle = poffCreateHandle(); + if (phandle == NULL) fatal(eNOMEMORY); + + /* Open the executable file */ + + if (!(exe = fopen(filename, "rb"))) + { + dbg("ERROR: Error opening '%s': %d\n", filename, errno); + goto errout_with_handle; + } + + /* Load the POFF file into memory */ + + err = poffReadFile(phandle, exe); + if (err != eNOERROR) + { + dbg("ERROR: Could not read %s: %d\n", filename, err); + goto errout_with_file; + } + + /* Verify that the file is a pascal executable */ + + ftype = poffGetFileType(phandle); + if (ftype != FHT_EXEC) + { + dbg("ERROR: File is not a pascal executable: %d\n", ftype); + goto errout_with_file; + } + + farch = poffGetArchitecture(phandle); + if (farch != FHA_PCODE_INSN16) + { + dbg("ERROR: File is not 16-bit pcode: %d\n", farch); + goto errout_with_file; + } + + /* Initialize the attribute structure */ + + attr.varsize = varsize; + attr.strsize = strsize; + + /* Extract the program entry point from the pascal executable */ + + attr.entry = poffGetEntryPoint(phandle); + + /* Close the POFF file */ + + (void)fclose(exe); + + /* Extract the program data from the POFF image */ + + attr.maxpc = poffExtractProgramData(phandle, &attr.ispace); + + /* Extract the read-only data from the POFF image */ + + attr.rosize = poffExtractRoData(phandle, &attr.rodata); + + /* Destroy the POFF image */ + + poffDestroyHandle(phandle); + + /* Initialize the p-code interpreter */ + + st = pexec_init(&attr); + if (!st && attr.ispace) + { + /* Initialization failed, discard the allocated I-Space */ + + free(st->ispace); + } + + /* Discard the allocated RO data in any event */ + + if (attr.rodata) + { + free(attr.rodata); + } + return st; + + errout_with_file: + (void)fclose(exe); + + errout_with_handle: + poffDestroyHandle(phandle); + return NULL; +} diff --git a/misc/pascal/insn16/prun/prun.c b/misc/pascal/insn16/prun/prun.c index 5db25ccf1..5a92ef43c 100644 --- a/misc/pascal/insn16/prun/prun.c +++ b/misc/pascal/insn16/prun/prun.c @@ -1,277 +1,279 @@ -/**************************************************************************** - * prun.c - * - * Copyright (C) 2008 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "keywords.h" -#include "pdefs.h" -#include "pinsn16.h" -#include "pxdefs.h" -#include "pedefs.h" - -#include "paslib.h" -#include "perr.h" -#include "pexec.h" -#include "pdbg.h" - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -#define MIN_STACK_SIZE 1024 -#define DEFAULT_STACK_SIZE 4096 -#define DEFAULT_STKSTR_SIZE 0 - -/**************************************************************************** - * Private Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -static const struct option long_options[] = -{ - {"stack", 1, NULL, 's'}, - {"string", 1, NULL, 't'}, - {"debug", 0, NULL, 'd'}, - {"help", 0, NULL, 'h'}, - {NULL, 0, NULL, 0} -}; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const char *g_pofffilename; -static sint32 g_varstacksize = DEFAULT_STACK_SIZE; -static sint32 g_strstacksize = DEFAULT_STKSTR_SIZE; -static int g_debug = 0; - -/**************************************************************************** - * Global Variables - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: prun_showusage - ****************************************************************************/ - -static void prun_showusage(const char *progname) -{ - fprintf(stderr, "Usage:\n"); - fprintf(stderr, " %s [options] \n", - progname); - fprintf(stderr, "options:\n"); - fprintf(stderr, " -s \n"); - fprintf(stderr, " --stack \n"); - fprintf(stderr, " Memory in bytes to allocate for the pascal program\n"); - fprintf(stderr, " stack in bytes (minimum is %d; default is %d bytes)\n", - MIN_STACK_SIZE, DEFAULT_STACK_SIZE); - fprintf(stderr, " -t \n"); - fprintf(stderr, " --string \n"); - fprintf(stderr, " Memory in bytes to allocate for the pascal program\n"); - fprintf(stderr, " string storage in bytes (default is %d bytes)\n", - DEFAULT_STKSTR_SIZE); - fprintf(stderr, " -d\n"); - fprintf(stderr, " --debug\n"); - fprintf(stderr, " Enable PCode program debugger\n"); - fprintf(stderr, " -h\n"); - fprintf(stderr, " --help\n"); - fprintf(stderr, " Shows this message\n"); - exit(1); -} - -/**************************************************************************** - * Name: prun_parseargs - ****************************************************************************/ - -static void prun_parseargs(int argc, char **argv) -{ - int option_index; - int size; - int c; - - /* Check for existence of filename argument */ - - if (argc < 2) - { - fprintf(stderr, "ERROR: Filename required\n"); - prun_showusage(argv[0]); - } /* end if */ - - /* Parse the command line options */ - - do - { - c = getopt_long (argc, argv, "t:s:dh", - long_options, &option_index); - if (c != -1) - { - switch (c) - { - case 's' : - size = atoi(optarg); - if (size < MIN_STACK_SIZE) - { - fprintf(stderr, "ERROR: Invalid stack size\n"); - prun_showusage(argv[0]); - } - g_varstacksize = (size + 3) & ~3; - break; - - case 't' : - size = atoi(optarg); - if (size < 0) - { - fprintf(stderr, "ERROR: Invalid string storage size\n"); - prun_showusage(argv[0]); - } - g_strstacksize = ((size + 3) & ~3); - break; - - case 'd' : - g_debug++; - break; - - case 'h' : - prun_showusage(argv[0]); - break; - - default: - /* Shouldn't happen */ - - fprintf(stderr, "ERROR: Unrecognized option\n"); - prun_showusage(argv[0]); - } - } - } - while (c != -1); - - if (optind != argc-1) - { - fprintf(stderr, "ERROR: Only one filename permitted on command line\n"); - prun_showusage(argv[0]); - } - - /* Get the name of the p-code file(s) from the last argument(s) */ - - g_pofffilename = argv[argc-1]; -} - -/**************************************************************************** - * Name: prun - * - * Description: - * This function executes the P-Code program until a stopping condition - * is encountered. - * - ****************************************************************************/ - -static void prun(struct pexec_s *st) -{ - int errcode; - - for (;;) - { - /* Execute the instruction; Check for exceptional conditions */ - - errcode = pexec(st); - if (errcode != eNOERROR) break; - } - - if (errcode != eEXIT) - { - printf("Runtime error 0x%02x -- Execution Stopped\n", errcode); - } -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: main - ****************************************************************************/ - -int main(int argc, char *argv[], char *envp[]) -{ - struct pexec_s *st; - char fileName[FNAME_SIZE+1]; /* Object file name */ - - /* Parse the command line arguments */ - - prun_parseargs(argc, argv); - - /* Load the POFF files specified on the command line */ - /* Use .o or command line extension, if supplied */ - - (void)extension(g_pofffilename, "o", fileName, 0); - - /* Load the POFF file */ - - st = pload(fileName, g_varstacksize, g_strstacksize); - if (!st) - { - fprintf(stderr, "ERROR: Could not load %s\n", fileName); - exit(1); - } /* end if */ - printf("%s Loaded\n", fileName); - - /* And start program execution in the specified mode */ - - if (g_debug) - dbg_run(st); - else - prun(st); - - /* Clean up resources used by the interpreter */ - - pexec_release(st); - return 0; - -} /* end main */ +/**************************************************************************** + * prun.c + * + * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "keywords.h" +#include "pdefs.h" +#include "pinsn16.h" +#include "pxdefs.h" +#include "pedefs.h" + +#include "paslib.h" +#include "perr.h" +#include "pexec.h" +#include "pdbg.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#define MIN_STACK_SIZE 1024 +#define DEFAULT_STACK_SIZE 4096 +#define DEFAULT_STKSTR_SIZE 0 + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Constant Data + ****************************************************************************/ + +static const struct option long_options[] = +{ + {"stack", 1, NULL, 's'}, + {"string", 1, NULL, 't'}, + {"debug", 0, NULL, 'd'}, + {"help", 0, NULL, 'h'}, + {NULL, 0, NULL, 0} +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const char *g_pofffilename; +static int32_t g_varstacksize = DEFAULT_STACK_SIZE; +static int32_t g_strstacksize = DEFAULT_STKSTR_SIZE; +static int g_debug = 0; + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: prun_showusage + ****************************************************************************/ + +static void prun_showusage(const char *progname) +{ + fprintf(stderr, "Usage:\n"); + fprintf(stderr, " %s [options] \n", + progname); + fprintf(stderr, "options:\n"); + fprintf(stderr, " -s \n"); + fprintf(stderr, " --stack \n"); + fprintf(stderr, " Memory in bytes to allocate for the pascal program\n"); + fprintf(stderr, " stack in bytes (minimum is %d; default is %d bytes)\n", + MIN_STACK_SIZE, DEFAULT_STACK_SIZE); + fprintf(stderr, " -t \n"); + fprintf(stderr, " --string \n"); + fprintf(stderr, " Memory in bytes to allocate for the pascal program\n"); + fprintf(stderr, " string storage in bytes (default is %d bytes)\n", + DEFAULT_STKSTR_SIZE); + fprintf(stderr, " -d\n"); + fprintf(stderr, " --debug\n"); + fprintf(stderr, " Enable PCode program debugger\n"); + fprintf(stderr, " -h\n"); + fprintf(stderr, " --help\n"); + fprintf(stderr, " Shows this message\n"); + exit(1); +} + +/**************************************************************************** + * Name: prun_parseargs + ****************************************************************************/ + +static void prun_parseargs(int argc, char **argv) +{ + int option_index; + int size; + int c; + + /* Check for existence of filename argument */ + + if (argc < 2) + { + fprintf(stderr, "ERROR: Filename required\n"); + prun_showusage(argv[0]); + } /* end if */ + + /* Parse the command line options */ + + do + { + c = getopt_long (argc, argv, "t:s:dh", + long_options, &option_index); + if (c != -1) + { + switch (c) + { + case 's' : + size = atoi(optarg); + if (size < MIN_STACK_SIZE) + { + fprintf(stderr, "ERROR: Invalid stack size\n"); + prun_showusage(argv[0]); + } + g_varstacksize = (size + 3) & ~3; + break; + + case 't' : + size = atoi(optarg); + if (size < 0) + { + fprintf(stderr, "ERROR: Invalid string storage size\n"); + prun_showusage(argv[0]); + } + g_strstacksize = ((size + 3) & ~3); + break; + + case 'd' : + g_debug++; + break; + + case 'h' : + prun_showusage(argv[0]); + break; + + default: + /* Shouldn't happen */ + + fprintf(stderr, "ERROR: Unrecognized option\n"); + prun_showusage(argv[0]); + } + } + } + while (c != -1); + + if (optind != argc-1) + { + fprintf(stderr, "ERROR: Only one filename permitted on command line\n"); + prun_showusage(argv[0]); + } + + /* Get the name of the p-code file(s) from the last argument(s) */ + + g_pofffilename = argv[argc-1]; +} + +/**************************************************************************** + * Name: prun + * + * Description: + * This function executes the P-Code program until a stopping condition + * is encountered. + * + ****************************************************************************/ + +static void prun(struct pexec_s *st) +{ + int errcode; + + for (;;) + { + /* Execute the instruction; Check for exceptional conditions */ + + errcode = pexec(st); + if (errcode != eNOERROR) break; + } + + if (errcode != eEXIT) + { + printf("Runtime error 0x%02x -- Execution Stopped\n", errcode); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: main + ****************************************************************************/ + +int main(int argc, char *argv[], char *envp[]) +{ + struct pexec_s *st; + char fileName[FNAME_SIZE+1]; /* Object file name */ + + /* Parse the command line arguments */ + + prun_parseargs(argc, argv); + + /* Load the POFF files specified on the command line */ + /* Use .o or command line extension, if supplied */ + + (void)extension(g_pofffilename, "o", fileName, 0); + + /* Load the POFF file */ + + st = pload(fileName, g_varstacksize, g_strstacksize); + if (!st) + { + fprintf(stderr, "ERROR: Could not load %s\n", fileName); + exit(1); + } /* end if */ + printf("%s Loaded\n", fileName); + + /* And start program execution in the specified mode */ + + if (g_debug) + dbg_run(st); + else + prun(st); + + /* Clean up resources used by the interpreter */ + + pexec_release(st); + return 0; + +} /* end main */ -- cgit v1.2.3