www.pudn.com > open_watcom.rar > alphains.c


/**************************************************************************** 
* 
*                            Open Watcom Project 
* 
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. 
* 
*  ======================================================================== 
* 
*    This file contains Original Code and/or Modifications of Original 
*    Code as defined in and that are subject to the Sybase Open Watcom 
*    Public License version 1.0 (the 'License'). You may not use this file 
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO 
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is 
*    provided with the Original Code and Modifications, and is also 
*    available at www.sybase.com/developer/opensource. 
* 
*    The Original Code and all software distributed under the License are 
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM 
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF 
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR 
*    NON-INFRINGEMENT. Please see the License for the specific language 
*    governing rights and limitations under the License. 
* 
*  ======================================================================== 
* 
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE 
*               DESCRIBE IT HERE! 
* 
****************************************************************************/ 
 
 
#include "as.h" 
 
static bool insErrFlag = FALSE;    // to tell whether we had problems or not 
 
#define INS( a, b, c, d, e ) { a, b, c, d, e, NULL } 
 
ins_table AlphaTable[] = { 
 /* INS( name,      opcode, funccode,   template,               method ), */ 
 // Memory Format Instructions 
    INS( "lda",     0x08,   0x0000,     IT_MEMORY_LDA,          ENUM_NONE ), 
    INS( "ldah",    0x09,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "ldf",     0x20,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "ldg",     0x21,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "ldl",     0x28,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "ldl_l",   0x2A,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "ldq",     0x29,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "ldq_l",   0x2B,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "ldq_u",   0x0B,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "lds",     0x22,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "ldt",     0x23,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "stf",     0x24,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "stg",     0x25,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "stl",     0x2C,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "stl_c",   0x2E,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "stq",     0x2D,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "stq_c",   0x2F,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "stq_u",   0x0F,   0x0000,     IT_MEMORY_ALL,          ENUM_NONE ), 
    INS( "sts",     0x26,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
    INS( "stt",     0x27,   0x0000,     IT_FP_MEMORY_ALL,       ENUM_NONE ), 
 // Memory Format Instructions with a function code 
    INS( "fetch",   0x18,   0x8000,     IT_MEMORY_B,            ENUM_NONE ), 
    INS( "fetch_m", 0x18,   0xA000,     IT_MEMORY_B,            ENUM_NONE ), 
    INS( "mb",      0x18,   0x4000,     IT_MEMORY_NONE,         ENUM_NONE ), 
    INS( "wmb",     0x18,   0x4400,     IT_MEMORY_NONE,         ENUM_NONE ), 
    INS( "rc",      0x18,   0xE000,     IT_MEMORY_A,            ENUM_NONE ), 
    INS( "rpcc",    0x18,   0xC000,     IT_MEMORY_A,            ENUM_NONE ), 
    INS( "rs",      0x18,   0xF000,     IT_MEMORY_A,            ENUM_NONE ), 
    INS( "trapb",   0x18,   0x0000,     IT_MEMORY_NONE,         ENUM_NONE ), 
    INS( "excb",    0x18,   0x0400,     IT_MEMORY_NONE,         ENUM_NONE ), 
 // Memory Branch Instructions 
    INS( "jmp",     0x1A,   0x0000,     IT_MEMORY_JUMP,         ENUM_NONE ), 
    INS( "jsr",     0x1A,   0x0001,     IT_MEMORY_JUMP,         ENUM_NONE ), 
    INS( "jsr_coroutine", 0x1A, 0x0003, IT_RET,                 ENUM_NONE ), 
    INS( "ret",     0x1A,   0x0002,     IT_RET,                 ENUM_NONE ), 
 // Branch Format Instructions 
    INS( "br",      0x30,   0x0000,     IT_BR,                  ENUM_NONE ), 
    INS( "fbeq",    0x31,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "fblt",    0x32,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "fble",    0x33,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "bsr",     0x34,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "fbne",    0x35,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "fbge",    0x36,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "fbgt",    0x37,   0x0000,     IT_FP_BRANCH,           ENUM_NONE ), 
    INS( "blbc",    0x38,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "beq",     0x39,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "blt",     0x3A,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "ble",     0x3B,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "blbs",    0x3C,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "bne",     0x3D,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "bge",     0x3E,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
    INS( "bgt",     0x3F,   0x0000,     IT_BRANCH,              ENUM_NONE ), 
 // Operate Format Instructions 
    INS( "addl",    0x10,   0x0000,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "addq",    0x10,   0x0020,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "cmpbge",  0x10,   0x000F,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmpeq",   0x10,   0x002D,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmple",   0x10,   0x006D,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmplt",   0x10,   0x004D,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmpule",  0x10,   0x003D,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmpult",  0x10,   0x001D,     IT_OPERATE,             ENUM_NONE ), 
    INS( "subl",    0x10,   0x0009,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "subq",    0x10,   0x0029,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "s4addl",  0x10,   0x0002,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s4addq",  0x10,   0x0022,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s4subl",  0x10,   0x000B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s4subq",  0x10,   0x002B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s8addl",  0x10,   0x0012,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s8addq",  0x10,   0x0032,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s8subl",  0x10,   0x001B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "s8subq",  0x10,   0x003B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "and",     0x11,   0x0000,     IT_OPERATE,             ENUM_NONE ), 
    INS( "bic",     0x11,   0x0008,     IT_OPERATE,             ENUM_NONE ), 
    INS( "bis",     0x11,   0x0020,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmoveq",  0x11,   0x0024,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovlbc", 0x11,   0x0016,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovlbs", 0x11,   0x0014,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovge",  0x11,   0x0046,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovgt",  0x11,   0x0066,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovle",  0x11,   0x0064,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovlt",  0x11,   0x0044,     IT_OPERATE,             ENUM_NONE ), 
    INS( "cmovne",  0x11,   0x0026,     IT_OPERATE,             ENUM_NONE ), 
    INS( "eqv",     0x11,   0x0048,     IT_OPERATE,             ENUM_NONE ), 
    INS( "ornot",   0x11,   0x0028,     IT_OPERATE,             ENUM_NONE ), 
    INS( "xor",     0x11,   0x0040,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extbl",   0x12,   0x0006,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extlh",   0x12,   0x006A,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extll",   0x12,   0x0026,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extqh",   0x12,   0x007A,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extql",   0x12,   0x0036,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extwh",   0x12,   0x005A,     IT_OPERATE,             ENUM_NONE ), 
    INS( "extwl",   0x12,   0x0016,     IT_OPERATE,             ENUM_NONE ), 
    INS( "insbl",   0x12,   0x000B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "inslh",   0x12,   0x0067,     IT_OPERATE,             ENUM_NONE ), 
    INS( "insll",   0x12,   0x002B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "insqh",   0x12,   0x0077,     IT_OPERATE,             ENUM_NONE ), 
    INS( "insql",   0x12,   0x003B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "inswh",   0x12,   0x0057,     IT_OPERATE,             ENUM_NONE ), 
    INS( "inswl",   0x12,   0x001B,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskbl",   0x12,   0x0002,     IT_OPERATE,             ENUM_NONE ), 
    INS( "msklh",   0x12,   0x0062,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskll",   0x12,   0x0022,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskqh",   0x12,   0x0072,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskql",   0x12,   0x0032,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskwh",   0x12,   0x0052,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mskwl",   0x12,   0x0012,     IT_OPERATE,             ENUM_NONE ), 
    INS( "sll",     0x12,   0x0039,     IT_OPERATE,             ENUM_NONE ), 
    INS( "sra",     0x12,   0x003C,     IT_OPERATE,             ENUM_NONE ), 
    INS( "srl",     0x12,   0x0034,     IT_OPERATE,             ENUM_NONE ), 
    INS( "zap",     0x12,   0x0030,     IT_OPERATE,             ENUM_NONE ), 
    INS( "zapnot",  0x12,   0x0031,     IT_OPERATE,             ENUM_NONE ), 
    INS( "mull",    0x13,   0x0000,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "mulq",    0x13,   0x0020,     IT_OPERATE,             ENUM_OF_ADDL ), 
    INS( "umulh",   0x13,   0x0030,     IT_OPERATE,             ENUM_NONE ), 
 // Floating-Point Operate Format Instructions - Data Type Independent 
    INS( "cpys",    0x17,   0x0020,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "cpyse",   0x17,   0x0022,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "cpysn",   0x17,   0x0021,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "cvtlq",   0x17,   0x0010,     IT_FP_CONVERT,          ENUM_NONE ), 
    INS( "cvtql",   0x17,   0x0030,     IT_FP_CONVERT,          ENUM_DTI_CVTQL ), 
    INS( "fcmoveq", 0x17,   0x002A,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "fcmovge", 0x17,   0x002D,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "fcmovgt", 0x17,   0x002F,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "fcmovle", 0x17,   0x002E,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "fcmovlt", 0x17,   0x002C,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "fcmovne", 0x17,   0x002B,     IT_FP_OPERATE,          ENUM_NONE ), 
    INS( "mf_fpcr", 0x17,   0x0025,     IT_MT_MF_FPCR,          ENUM_NONE ), 
    INS( "mt_fpcr", 0x17,   0x0024,     IT_MT_MF_FPCR,          ENUM_NONE ), 
 // Floating-Point Operate Format Instructions - IEEE 
    INS( "adds",    0x16,   0x0080,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "addt",    0x16,   0x00A0,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "cmpteq",  0x16,   0x00A5,     IT_FP_OPERATE,          ENUM_IEEE_CMPTEQ ), 
    INS( "cmptlt",  0x16,   0x00A6,     IT_FP_OPERATE,          ENUM_IEEE_CMPTEQ ), 
    INS( "cmptle",  0x16,   0x00A7,     IT_FP_OPERATE,          ENUM_IEEE_CMPTEQ ), 
    INS( "cmptun",  0x16,   0x00A4,     IT_FP_OPERATE,          ENUM_IEEE_CMPTEQ ), 
    INS( "cvtqs",   0x16,   0x00BC,     IT_FP_CONVERT,          ENUM_IEEE_CVTQS ), 
    INS( "cvtqt",   0x16,   0x00BE,     IT_FP_CONVERT,          ENUM_IEEE_CVTQS ), 
    INS( "cvtts",   0x16,   0x00AC,     IT_FP_CONVERT,          ENUM_IEEE_ADDS ), 
    INS( "divs",    0x16,   0x0083,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "divt",    0x16,   0x00A3,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "muls",    0x16,   0x0082,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "mult",    0x16,   0x00A2,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "subs",    0x16,   0x0081,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "subt",    0x16,   0x00A1,     IT_FP_OPERATE,          ENUM_IEEE_ADDS ), 
    INS( "cvttq",   0x16,   0x00AF,     IT_FP_CONVERT,          ENUM_IEEE_CVTTQ ), 
 // Floating-Point Operate Format Instructions - VAX 
    INS( "addf",    0x15,   0x0080,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "cvtdg",   0x15,   0x009E,     IT_FP_CONVERT,          ENUM_VAX_ADDF ), 
    INS( "addg",    0x15,   0x00A0,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "cmpgeq",  0x15,   0x00A5,     IT_FP_OPERATE,          ENUM_VAX_CMPGEQ ), 
    INS( "cmpglt",  0x15,   0x00A6,     IT_FP_OPERATE,          ENUM_VAX_CMPGEQ ), 
    INS( "cmpgle",  0x15,   0x00A7,     IT_FP_OPERATE,          ENUM_VAX_CMPGEQ ), 
    INS( "cvtgf",   0x15,   0x00AC,     IT_FP_CONVERT,          ENUM_VAX_ADDF ), 
    INS( "cvtgd",   0x15,   0x00AD,     IT_FP_CONVERT,          ENUM_VAX_ADDF ), 
    INS( "cvtqf",   0x15,   0x00BC,     IT_FP_CONVERT,          ENUM_VAX_CVTQF ), 
    INS( "cvtqg",   0x15,   0x00BE,     IT_FP_CONVERT,          ENUM_VAX_CVTQF ), 
    INS( "divf",    0x15,   0x0083,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "divg",    0x15,   0x00A3,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "mulf",    0x15,   0x0082,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "mulg",    0x15,   0x00A2,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "subf",    0x15,   0x0081,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "subg",    0x15,   0x00A1,     IT_FP_OPERATE,          ENUM_VAX_ADDF ), 
    INS( "cvtgq",   0x15,   0x00AF,     IT_FP_CONVERT,          ENUM_VAX_CVTGQ ), 
 // PALcode 
    INS( "call_pal",0x00,   0x0000,     IT_CALL_PAL,            ENUM_NONE ), 
 // Stylized Code Forms 
    // nop and fnop are in directiv.c since they don't require much parsing 
    INS( "clr",     0x11,   0x0020,     IT_PSEUDO_CLR,          ENUM_NONE ), 
    INS( "fclr",    0x17,   0x0020,     IT_PSEUDO_FCLR,         ENUM_NONE ), 
    INS( "fmov",    0x17,   0x0020,     IT_PSEUDO_FMOV,         ENUM_NONE ), 
    INS( "negl",    0x10,   0x0009,     IT_PSEUDO_NOT,          ENUM_OF_ADDL ), 
    INS( "negq",    0x10,   0x0029,     IT_PSEUDO_NOT,          ENUM_OF_ADDL ), 
    INS( "negf",    0x15,   0x0081,     IT_PSEUDO_NEGF,         ENUM_VAX_ADDF ), 
    INS( "negg",    0x15,   0x00A1,     IT_PSEUDO_NEGF,         ENUM_VAX_ADDF ), 
    INS( "negs",    0x16,   0x0081,     IT_PSEUDO_NEGF,         ENUM_IEEE_ADDS ), 
    INS( "negt",    0x16,   0x00A1,     IT_PSEUDO_NEGF,         ENUM_IEEE_ADDS ), 
    INS( "fneg",    0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ), 
    INS( "fnegf",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ), 
    INS( "fnegg",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ), 
    INS( "fnegs",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ), 
    INS( "fnegt",   0x17,   0x0021,     IT_PSEUDO_FNEG,         ENUM_NONE ), 
    INS( "not",     0x11,   0x0028,     IT_PSEUDO_NOT,          ENUM_NONE ), 
    INS( "or",      0x11,   0x0020,     IT_OPERATE,             ENUM_NONE ), 
    INS( "andnot",  0x11,   0x0008,     IT_OPERATE,             ENUM_NONE ), 
    INS( "xornot",  0x11,   0x0048,     IT_OPERATE,             ENUM_NONE ), 
    INS( "fabs",    0x17,   0x0020,     IT_PSEUDO_NEGF,         ENUM_NONE ), 
    INS( "sextl",   0x10,   0x0000,     IT_PSEUDO_NOT,          ENUM_NONE ), 
 // The following pseudo-instructions might emit multiple real instructions 
    INS( "mov",     0x11,   0x0020,     IT_PSEUDO_MOV,          ENUM_NONE ), 
    // abs pseudo ins (opcode & funccode are from subl/v, subq/v) 
    INS( "absl",    0x10,   0x0049,     IT_PSEUDO_ABS,          ENUM_NONE ), 
    INS( "absq",    0x10,   0x0069,     IT_PSEUDO_ABS,          ENUM_NONE ), 
 
#if 0 
 // NYI: (more pseudo-ins that are in MS asaxp) 
 //-------------------------------------------- 
    // Load instructions that emits more than one instructions 
    INS( "ldb",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ldbu",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ldw",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ldwu",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "uldw",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "uldwu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "uldl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "uldq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    // Store instructions that emits more than one instructions 
    INS( "stb",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "stw",     0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ustw",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ustl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "ustq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    // Integer divide and remainder instructions that are unsupported in 
    // hardward level. 
    // (MS asaxp does this by generating bsr to some _div function elsewhere) 
    INS( "divl",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "divlu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "divq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "divqu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "reml",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "remlu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "remq",    0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
    INS( "remqu",   0x??,   0x????,     IT_PSEUDO_????,         ENUM_NONE ), 
#endif 
}; 
 
#define MAX_NAME_LEN    20  // maximum length of an Alpha instruction mnemonic 
 
static void addInstructionSymbol( qualifier_flags flags, ins_table *table_entry ) { 
//********************************************************************************* 
// Given an instruction name for which the optional bits in flags 
// are turned on, add a symbol for it to the symbol table. 
 
    sym_handle  sym; 
    ins_symbol  *entry; 
    char        buffer[ MAX_NAME_LEN ]; 
 
    strcpy( buffer, table_entry->name ); 
    if( flags ) { 
        strcat( buffer, "/" ); 
        if( flags & QF_S ) strcat( buffer, "s" ); 
 
        if( flags & QF_U ) strcat( buffer, "u" );   // u & v are mutually 
        if( flags & QF_V ) strcat( buffer, "v" );   // exclusive 
 
        if( flags & QF_I ) strcat( buffer, "i" ); 
 
        if( flags & QF_C ) strcat( buffer, "c" );   // c, m, & d are 
        if( flags & QF_M ) strcat( buffer, "m" );   // mutually exclusive 
        if( flags & QF_D ) strcat( buffer, "d" ); 
    } 
 
    entry = MemAlloc( sizeof( ins_symbol ) ); 
    entry->table_entry = table_entry; 
    entry->flags = flags; 
 
    // link it into our list of symbols for this table entry 
    entry->next = table_entry->symbols; 
    table_entry->symbols = entry; 
 
    sym = SymAdd( buffer, SYM_INSTRUCTION ); 
    SymSetLink( sym, (void *)entry ); 
} 
 
static void enum_NONE( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//******************************************************************************************************************************** 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
} 
 
static void enum_OF_ADDL( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//*********************************************************************************************************************************** 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
    func( QF_V, parm ); 
} 
 
static void enum_DTI_CVTQL( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//************************************************************************************************************************************* 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
    func( QF_V, parm ); 
    func( QF_S | QF_V, parm ); 
} 
 
static void enum_IEEE_CMPTEQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//*************************************************************************************************************************************** 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
    func( QF_S | QF_U, parm ); 
} 
 
static void enum_IEEE_CVTQS( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//************************************************************************************************************************************** 
 
    assert( level < 2 ); 
    switch( level ) { 
    case 0: 
        enum_IEEE_CVTQS( method, mask, level + 1, func, parm ); 
        mask |= ( QF_S | QF_U | QF_I ); 
        enum_IEEE_CVTQS( method, mask, level + 1, func, parm ); 
        break; 
    case 1: 
        func( mask, parm ); 
        mask |= QF_C; 
        func( mask, parm ); 
        mask &= ~QF_C; 
        mask |= QF_M; 
        func( mask, parm ); 
        mask &= ~QF_M; 
        mask |= QF_D; 
        func( mask, parm ); 
        break; 
    } 
} 
 
static void enum_VAX_ADDF_or_CVTGQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//********************************************************************************************************************************************* 
 
    assert( level < 3 ); 
    switch( level ) { 
    case 0: 
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm ); 
        mask |= QF_S; 
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm ); 
        break; 
    case 1: 
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm ); 
        mask |= ( ( method == ENUM_VAX_ADDF ) ? QF_U : QF_V ); 
        enum_VAX_ADDF_or_CVTGQ( method, mask, level + 1, func, parm ); 
        break; 
    case 2: 
        func( mask, parm ); 
        mask |= QF_C; 
        func( mask, parm ); 
        break; 
    } 
} 
 
static void enum_VAX_CMPGEQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//************************************************************************************************************************************** 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
    func( QF_S, parm ); 
} 
 
static void enum_VAX_CVTQF( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//************************************************************************************************************************************* 
 
    method = method; 
    level = level; 
    mask = mask; 
    func( QF_NONE, parm ); 
    func( QF_C, parm ); 
} 
 
static void enum_IEEE_ADDS_or_CVTTQ( ins_enum_method method, uint_32 mask, uint_8 level, void (*func)( qualifier_flags, ins_table * ), void *parm ) { 
//********************************************************************************************************************************************** 
 
    assert( level < 4 ); 
    switch( level ) { 
    case 0: 
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        mask |= QF_S; 
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        break; 
    case 1: 
        if( !mask ) { 
            enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        } 
        mask |= ( ( method == ENUM_IEEE_ADDS ) ? QF_U : QF_V ); 
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        break; 
    case 2: 
        enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        if( mask & QF_S ) { 
            mask |= QF_I; 
            enum_IEEE_ADDS_or_CVTTQ( method, mask, level + 1, func, parm ); 
        } 
        break; 
    case 3: 
        func( mask, parm ); 
        mask |= QF_C; 
        func( mask, parm ); 
        mask &= ~QF_C; 
        mask |= QF_M; 
        func( mask, parm ); 
        mask &= ~QF_M; 
        mask |= QF_D; 
        func( mask, parm ); 
        break; 
    } 
} 
 
typedef void (*enumFunc_t)( ins_enum_method, uint_32, uint_8, void (*func)( qualifier_flags, ins_table * ), void * ); 
 
#define PICK( a, b )    b, 
static enumFunc_t enumFunc[] = { 
#include "insenum.inc" 
}; 
#undef PICK 
 
static void enumInstructions( ins_enum_method method, void (*func)( qualifier_flags set, ins_table *parm ), void *parm ) { 
//************************************************************************************************ 
// Depending on which enum_method it belongs to, different instruction- 
// enumeration functions will be called to generate all the possible 
// instructions with the different qualifiers attached. 
 
    enumFunc[method]( method, QF_NONE, 0, func, parm ); 
} 
 
#ifdef _STANDALONE_ 
#ifndef NDEBUG 
static char *itStrings[] = { 
#define PICK( a, b, c, d, e ) #a, 
#include "alphafmt.inc" 
#undef PICK 
}; 
 
extern void DumpITString( ins_template template ) { 
    printf( itStrings[ template ] ); 
} 
 
static char *insEnumStrings[] = { 
#define PICK( a, b ) #a, 
#include "insenum.inc" 
#undef PICK 
}; 
 
extern void DumpInsEnumMethod( ins_enum_method method ) { 
//******************************************************* 
 
    printf( insEnumStrings[ method ] ); 
} 
 
extern void DumpInsTableEntry( ins_table *table_entry ) { 
//******************************************************* 
 
    ins_symbol  *symbol; 
 
    printf( "%s: 0x%x(0x%x) ", table_entry->name, table_entry->opcode, table_entry->funccode ); 
    DumpITString( table_entry->template ); 
    printf( ", " ); 
    DumpInsEnumMethod( table_entry->method ); 
    printf( "\n\tSymbol entries: " ); 
    symbol = table_entry->symbols; 
    while( symbol != NULL ) { 
        printf( " %x", symbol ); 
        symbol = symbol->next; 
    } 
    printf( "\n" ); 
} 
 
extern void DumpInsTables() { 
//*************************** 
 
    ins_table   *curr; 
    int         i, n; 
 
    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] ); 
    for( i = 0; i < n; i++ ) { 
        curr = &AlphaTable[ i ]; 
        DumpInsTableEntry( curr ); 
    } 
} 
#endif 
#endif 
 
extern void InsInit() { 
//********************* 
 
    ins_table   *curr; 
    int         i, n; 
 
    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] ); 
    for( i = 0; i < n; i++ ) { 
        curr = &AlphaTable[ i ]; 
        /* for each possible symbol generated by this instruction, add a symbol table entry */ 
        enumInstructions( curr->method, addInstructionSymbol, curr ); 
    } 
#ifndef NDEBUG 
    #ifdef _STANDALONE_ 
    if( _IsOption( DUMP_INS_TABLE ) ) DumpInsTables(); 
    #endif 
#endif 
} 
 
extern instruction *InsCreate( sym_handle op_sym ) { 
//************************************************** 
// Allocate an instruction and initialize it. 
 
    instruction *ins; 
 
    ins = MemAlloc( sizeof( instruction ) ); 
    ins->opcode_sym = op_sym; 
    ins->format = SymGetLink( op_sym ); 
    ins->num_operands = 0; 
    return( ins ); 
} 
 
extern void InsAddOperand( instruction *ins, ins_operand *op ) { 
//********************************************************** 
// Add an operand to the given instruction. 
 
    if( ins->num_operands == MAX_OPERANDS ) { 
        if( !insErrFlag ) { 
            Error( MAX_NUMOP_EXCEEDED ); 
            insErrFlag = TRUE; 
        } 
        MemFree( op ); 
        return; 
    } 
    if( insErrFlag) insErrFlag = FALSE; 
    ins->operands[ ins->num_operands++ ] = op; 
} 
 
extern void InsEmit( instruction *ins ) { 
//*************************************** 
// Check an instruction to make sure operands match 
// and encode it. The encoded instruction is emitted 
// to the current OWL section. 
 
#ifndef NDEBUG 
    #ifdef _STANDALONE_ 
    if( _IsOption( DUMP_INSTRUCTIONS ) ) { 
        DumpIns( ins ); 
    } 
    #endif 
#endif 
    if( insErrFlag == FALSE && AlphaValidate( ins ) ) { 
        #ifdef _STANDALONE_ 
        AlphaEmit( CurrentSection, ins ); 
        #else 
        AlphaEmit( ins ); 
        #endif 
    } 
} 
 
extern void InsDestroy( instruction *ins ) { 
//****************************************** 
// Free up an instruction and all operands which 
// are hanging off of it. 
 
    int         i; 
 
    for( i = 0; i < ins->num_operands; i++ ) { 
        MemFree( ins->operands[ i ] ); 
    } 
    MemFree( ins ); 
} 
 
extern void InsFini() { 
//********************* 
 
    ins_table   *curr; 
    ins_symbol  *next; 
    ins_symbol  *entry; 
    int         i, n; 
    extern instruction *AsCurrIns; // from as.y 
 
    if( AsCurrIns != NULL ) { 
        InsDestroy( AsCurrIns ); 
        AsCurrIns = NULL; 
    } 
    n = sizeof( AlphaTable ) / sizeof( AlphaTable[0] ); 
    for( i = 0; i < n; i++ ) { 
        curr = &AlphaTable[ i ]; 
        for( entry = curr->symbols; entry != NULL; entry = next ) { 
            next = entry->next; 
            MemFree( entry ); 
        } 
        curr->symbols = NULL;   // need to reset this pointer 
    } 
} 
 
#ifdef _STANDALONE_ 
#ifndef NDEBUG 
extern void DumpIns( instruction *ins ) { 
//*************************************** 
 
    int         i; 
 
    printf( "%-11s", SymName( ins->opcode_sym ) ); 
    for( i = 0; i < ins->num_operands; i++ ) { 
        if( i != 0 ) printf( ", " ); 
        DumpOperand( ins->operands[ i ] ); 
    } 
    printf( "\n" ); 
} 
#endif 
#endif