| /* Generated by re2c 0.9.1-C on Wed May 14 18:37:56 2008 |
| */ |
| #line 1 "./modules/arch/lc3b/lc3bid.re" |
| /* |
| * LC-3b identifier recognition and instruction handling |
| * |
| * Copyright (C) 2003-2007 Peter Johnson |
| * |
| * 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. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER 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 AUTHOR OR OTHER 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 <util.h> |
| RCSID("$Id: lc3bid.c,v 1.1.1.1 2012/03/29 17:20:58 uid42307 Exp $"); |
| |
| #include <libyasm.h> |
| |
| #include "modules/arch/lc3b/lc3barch.h" |
| |
| |
| /* Opcode modifiers. The opcode bytes are in "reverse" order because the |
| * parameters are read from the arch-specific data in LSB->MSB order. |
| * (only for asthetic reasons in the lexer code below, no practical reason). |
| */ |
| #define MOD_OpHAdd (1UL<<0) /* Parameter adds to upper 8 bits of insn */ |
| #define MOD_OpLAdd (1UL<<1) /* Parameter adds to lower 8 bits of insn */ |
| |
| /* Operand types. These are more detailed than the "general" types for all |
| * architectures, as they include the size, for instance. |
| * Bit Breakdown (from LSB to MSB): |
| * - 1 bit = general type (must be exact match, except for =3): |
| * 0 = immediate |
| * 1 = register |
| * |
| * MSBs than the above are actions: what to do with the operand if the |
| * instruction matches. Essentially describes what part of the output bytecode |
| * gets the operand. This may require conversion (e.g. a register going into |
| * an ea field). Naturally, only one of each of these may be contained in the |
| * operands of a single insn_info structure. |
| * - 2 bits = action: |
| * 0 = does nothing (operand data is discarded) |
| * 1 = DR field |
| * 2 = SR field |
| * 3 = immediate |
| * |
| * Immediate operands can have different sizes. |
| * - 3 bits = size: |
| * 0 = no immediate |
| * 1 = 4-bit immediate |
| * 2 = 5-bit immediate |
| * 3 = 6-bit index, word (16 bit)-multiple |
| * 4 = 6-bit index, byte-multiple |
| * 5 = 8-bit immediate, word-multiple |
| * 6 = 9-bit signed immediate, word-multiple |
| * 7 = 9-bit signed offset from next PC ($+2), word-multiple |
| */ |
| #define OPT_Imm 0x0 |
| #define OPT_Reg 0x1 |
| #define OPT_MASK 0x1 |
| |
| #define OPA_None (0<<1) |
| #define OPA_DR (1<<1) |
| #define OPA_SR (2<<1) |
| #define OPA_Imm (3<<1) |
| #define OPA_MASK (3<<1) |
| |
| #define OPI_None (LC3B_IMM_NONE<<3) |
| #define OPI_4 (LC3B_IMM_4<<3) |
| #define OPI_5 (LC3B_IMM_5<<3) |
| #define OPI_6W (LC3B_IMM_6_WORD<<3) |
| #define OPI_6B (LC3B_IMM_6_BYTE<<3) |
| #define OPI_8 (LC3B_IMM_8<<3) |
| #define OPI_9 (LC3B_IMM_9<<3) |
| #define OPI_9PC (LC3B_IMM_9_PC<<3) |
| #define OPI_MASK (7<<3) |
| |
| typedef struct lc3b_insn_info { |
| /* Opcode modifiers for variations of instruction. As each modifier reads |
| * its parameter in LSB->MSB order from the arch-specific data[1] from the |
| * lexer data, and the LSB of the arch-specific data[1] is reserved for the |
| * count of insn_info structures in the instruction grouping, there can |
| * only be a maximum of 3 modifiers. |
| */ |
| unsigned int modifiers; |
| |
| /* The basic 2 byte opcode */ |
| unsigned int opcode; |
| |
| /* The number of operands this form of the instruction takes */ |
| unsigned char num_operands; |
| |
| /* The types of each operand, see above */ |
| unsigned int operands[3]; |
| } lc3b_insn_info; |
| |
| typedef struct lc3b_id_insn { |
| yasm_insn insn; /* base structure */ |
| |
| /* instruction parse group - NULL if empty instruction (just prefixes) */ |
| /*@null@*/ const lc3b_insn_info *group; |
| |
| /* Modifier data */ |
| unsigned long mod_data; |
| |
| /* Number of elements in the instruction parse group */ |
| unsigned int num_info:8; |
| } lc3b_id_insn; |
| |
| static void lc3b_id_insn_destroy(void *contents); |
| static void lc3b_id_insn_print(const void *contents, FILE *f, int indent_level); |
| static void lc3b_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); |
| |
| static const yasm_bytecode_callback lc3b_id_insn_callback = { |
| lc3b_id_insn_destroy, |
| lc3b_id_insn_print, |
| lc3b_id_insn_finalize, |
| yasm_bc_calc_len_common, |
| yasm_bc_expand_common, |
| yasm_bc_tobytes_common, |
| YASM_BC_SPECIAL_INSN |
| }; |
| |
| /* |
| * Instruction groupings |
| */ |
| |
| static const lc3b_insn_info empty_insn[] = { |
| { 0, 0, 0, {0, 0, 0} } |
| }; |
| |
| static const lc3b_insn_info addand_insn[] = { |
| { MOD_OpHAdd, 0x1000, 3, |
| {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, OPT_Reg|OPA_Imm|OPI_5} }, |
| { MOD_OpHAdd, 0x1020, 3, |
| {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, OPT_Imm|OPA_Imm|OPI_5} } |
| }; |
| |
| static const lc3b_insn_info br_insn[] = { |
| { MOD_OpHAdd, 0x0000, 1, {OPT_Imm|OPA_Imm|OPI_9PC, 0, 0} } |
| }; |
| |
| static const lc3b_insn_info jmp_insn[] = { |
| { 0, 0xC000, 2, {OPT_Reg|OPA_DR, OPT_Imm|OPA_Imm|OPI_9, 0} } |
| }; |
| |
| static const lc3b_insn_info lea_insn[] = { |
| { 0, 0xE000, 2, {OPT_Reg|OPA_DR, OPT_Imm|OPA_Imm|OPI_9PC, 0} } |
| }; |
| |
| static const lc3b_insn_info ldst_insn[] = { |
| { MOD_OpHAdd, 0x0000, 3, |
| {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, OPT_Imm|OPA_Imm|OPI_6W} } |
| }; |
| |
| static const lc3b_insn_info ldstb_insn[] = { |
| { MOD_OpHAdd, 0x0000, 3, |
| {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, OPT_Imm|OPA_Imm|OPI_6B} } |
| }; |
| |
| static const lc3b_insn_info not_insn[] = { |
| { 0, 0x903F, 2, {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, 0} } |
| }; |
| |
| static const lc3b_insn_info nooperand_insn[] = { |
| { MOD_OpHAdd, 0x0000, 0, {0, 0, 0} } |
| }; |
| |
| static const lc3b_insn_info shift_insn[] = { |
| { MOD_OpLAdd, 0xD000, 3, |
| {OPT_Reg|OPA_DR, OPT_Reg|OPA_SR, OPT_Imm|OPA_Imm|OPI_4} } |
| }; |
| |
| static const lc3b_insn_info trap_insn[] = { |
| { 0, 0xF000, 1, {OPT_Imm|OPA_Imm|OPI_8, 0, 0} } |
| }; |
| |
| static void |
| lc3b_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) |
| { |
| lc3b_id_insn *id_insn = (lc3b_id_insn *)bc->contents; |
| lc3b_insn *insn; |
| int num_info = id_insn->num_info; |
| const lc3b_insn_info *info = id_insn->group; |
| unsigned long mod_data = id_insn->mod_data; |
| int found = 0; |
| yasm_insn_operand *op; |
| int i; |
| |
| yasm_insn_finalize(&id_insn->insn); |
| |
| /* Just do a simple linear search through the info array for a match. |
| * First match wins. |
| */ |
| for (; num_info>0 && !found; num_info--, info++) { |
| int mismatch = 0; |
| |
| /* Match # of operands */ |
| if (id_insn->insn.num_operands != info->num_operands) |
| continue; |
| |
| if (id_insn->insn.num_operands == 0) { |
| found = 1; /* no operands -> must have a match here. */ |
| break; |
| } |
| |
| /* Match each operand type and size */ |
| for(i = 0, op = yasm_insn_ops_first(&id_insn->insn); |
| op && i<info->num_operands && !mismatch; |
| op = yasm_insn_op_next(op), i++) { |
| /* Check operand type */ |
| switch ((int)(info->operands[i] & OPT_MASK)) { |
| case OPT_Imm: |
| if (op->type != YASM_INSN__OPERAND_IMM) |
| mismatch = 1; |
| break; |
| case OPT_Reg: |
| if (op->type != YASM_INSN__OPERAND_REG) |
| mismatch = 1; |
| break; |
| default: |
| yasm_internal_error(N_("invalid operand type")); |
| } |
| |
| if (mismatch) |
| break; |
| } |
| |
| if (!mismatch) { |
| found = 1; |
| break; |
| } |
| } |
| |
| if (!found) { |
| /* Didn't find a matching one */ |
| yasm_error_set(YASM_ERROR_TYPE, |
| N_("invalid combination of opcode and operands")); |
| return; |
| } |
| |
| /* Copy what we can from info */ |
| insn = yasm_xmalloc(sizeof(lc3b_insn)); |
| yasm_value_initialize(&insn->imm, NULL, 0); |
| insn->imm_type = LC3B_IMM_NONE; |
| insn->opcode = info->opcode; |
| |
| /* Apply modifiers */ |
| if (info->modifiers & MOD_OpHAdd) { |
| insn->opcode += ((unsigned int)(mod_data & 0xFF))<<8; |
| mod_data >>= 8; |
| } |
| if (info->modifiers & MOD_OpLAdd) { |
| insn->opcode += (unsigned int)(mod_data & 0xFF); |
| /*mod_data >>= 8;*/ |
| } |
| |
| /* Go through operands and assign */ |
| if (id_insn->insn.num_operands > 0) { |
| for(i = 0, op = yasm_insn_ops_first(&id_insn->insn); |
| op && i<info->num_operands; op = yasm_insn_op_next(op), i++) { |
| |
| switch ((int)(info->operands[i] & OPA_MASK)) { |
| case OPA_None: |
| /* Throw away the operand contents */ |
| if (op->type == YASM_INSN__OPERAND_IMM) |
| yasm_expr_destroy(op->data.val); |
| break; |
| case OPA_DR: |
| if (op->type != YASM_INSN__OPERAND_REG) |
| yasm_internal_error(N_("invalid operand conversion")); |
| insn->opcode |= ((unsigned int)(op->data.reg & 0x7)) << 9; |
| break; |
| case OPA_SR: |
| if (op->type != YASM_INSN__OPERAND_REG) |
| yasm_internal_error(N_("invalid operand conversion")); |
| insn->opcode |= ((unsigned int)(op->data.reg & 0x7)) << 6; |
| break; |
| case OPA_Imm: |
| insn->imm_type = (info->operands[i] & OPI_MASK)>>3; |
| switch (op->type) { |
| case YASM_INSN__OPERAND_IMM: |
| if (insn->imm_type == LC3B_IMM_6_WORD |
| || insn->imm_type == LC3B_IMM_8 |
| || insn->imm_type == LC3B_IMM_9 |
| || insn->imm_type == LC3B_IMM_9_PC) |
| op->data.val = yasm_expr_create(YASM_EXPR_SHR, |
| yasm_expr_expr(op->data.val), |
| yasm_expr_int(yasm_intnum_create_uint(1)), |
| op->data.val->line); |
| if (yasm_value_finalize_expr(&insn->imm, |
| op->data.val, |
| prev_bc, 0)) |
| yasm_error_set(YASM_ERROR_TOO_COMPLEX, |
| N_("immediate expression too complex")); |
| break; |
| case YASM_INSN__OPERAND_REG: |
| if (yasm_value_finalize_expr(&insn->imm, |
| yasm_expr_create_ident(yasm_expr_int( |
| yasm_intnum_create_uint(op->data.reg & 0x7)), |
| bc->line), prev_bc, 0)) |
| yasm_internal_error(N_("reg expr too complex?")); |
| break; |
| default: |
| yasm_internal_error(N_("invalid operand conversion")); |
| } |
| break; |
| default: |
| yasm_internal_error(N_("unknown operand action")); |
| } |
| |
| /* Clear so it doesn't get destroyed */ |
| op->type = YASM_INSN__OPERAND_REG; |
| } |
| |
| if (insn->imm_type == LC3B_IMM_9_PC) { |
| if (insn->imm.seg_of || insn->imm.rshift > 1 |
| || insn->imm.curpos_rel) |
| yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target")); |
| insn->imm.curpos_rel = 1; |
| } |
| } |
| |
| /* Transform the bytecode */ |
| yasm_lc3b__bc_transform_insn(bc, insn); |
| } |
| |
| |
| #define YYCTYPE unsigned char |
| #define YYCURSOR id |
| #define YYLIMIT id |
| #define YYMARKER marker |
| #define YYFILL(n) (void)(n) |
| |
| yasm_arch_regtmod |
| yasm_lc3b__parse_check_regtmod(yasm_arch *arch, const char *oid, size_t id_len, |
| uintptr_t *data) |
| { |
| const YYCTYPE *id = (const YYCTYPE *)oid; |
| /*const char *marker;*/ |
| |
| #line 358 "lc3bid.c" |
| { |
| YYCTYPE yych; |
| goto yy0; |
| ++YYCURSOR; |
| yy0: |
| if((YYLIMIT - YYCURSOR) < 3) YYFILL(3); |
| yych = *YYCURSOR; |
| if(yych <= 'R'){ |
| if(yych <= '\000') goto yy6; |
| if(yych <= 'Q') goto yy4; |
| goto yy2; |
| } else { |
| if(yych != 'r') goto yy4; |
| goto yy2; |
| } |
| yy2: yych = *++YYCURSOR; |
| if(yych <= '/') goto yy5; |
| if(yych <= '7') goto yy8; |
| goto yy5; |
| yy3: |
| #line 362 "./modules/arch/lc3b/lc3bid.re" |
| { |
| return YASM_ARCH_NOTREGTMOD; |
| } |
| #line 383 "lc3bid.c" |
| yy4: ++YYCURSOR; |
| if(YYLIMIT == YYCURSOR) YYFILL(1); |
| yych = *YYCURSOR; |
| goto yy5; |
| yy5: if(yych <= '\000') goto yy3; |
| goto yy4; |
| yy6: yych = *++YYCURSOR; |
| goto yy7; |
| yy7: |
| #line 365 "./modules/arch/lc3b/lc3bid.re" |
| { |
| return YASM_ARCH_NOTREGTMOD; |
| } |
| #line 397 "lc3bid.c" |
| yy8: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy4; |
| goto yy9; |
| yy9: |
| #line 356 "./modules/arch/lc3b/lc3bid.re" |
| { |
| *data = (oid[1]-'0'); |
| return YASM_ARCH_REG; |
| } |
| #line 407 "lc3bid.c" |
| } |
| #line 368 "./modules/arch/lc3b/lc3bid.re" |
| |
| } |
| |
| #define RET_INSN(g, m) \ |
| do { \ |
| group = g##_insn; \ |
| mod = m; \ |
| nelems = NELEMS(g##_insn); \ |
| goto done; \ |
| } while(0) |
| |
| yasm_arch_insnprefix |
| yasm_lc3b__parse_check_insnprefix(yasm_arch *arch, const char *oid, |
| size_t id_len, unsigned long line, |
| yasm_bytecode **bc, uintptr_t *prefix) |
| { |
| const YYCTYPE *id = (const YYCTYPE *)oid; |
| const lc3b_insn_info *group = empty_insn; |
| unsigned long mod = 0; |
| unsigned int nelems = NELEMS(empty_insn); |
| lc3b_id_insn *id_insn; |
| |
| *bc = (yasm_bytecode *)NULL; |
| *prefix = 0; |
| |
| /*const char *marker;*/ |
| |
| #line 437 "lc3bid.c" |
| { |
| YYCTYPE yych; |
| goto yy10; |
| ++YYCURSOR; |
| yy10: |
| if((YYLIMIT - YYCURSOR) < 6) YYFILL(6); |
| yych = *YYCURSOR; |
| if(yych <= 'T'){ |
| if(yych <= 'K'){ |
| if(yych <= 'A'){ |
| if(yych <= '\000') goto yy23; |
| if(yych <= '@') goto yy21; |
| goto yy12; |
| } else { |
| if(yych <= 'B') goto yy14; |
| if(yych == 'J') goto yy15; |
| goto yy21; |
| } |
| } else { |
| if(yych <= 'N'){ |
| if(yych <= 'L') goto yy16; |
| if(yych <= 'M') goto yy21; |
| goto yy18; |
| } else { |
| if(yych <= 'Q') goto yy21; |
| if(yych <= 'R') goto yy19; |
| if(yych <= 'S') goto yy17; |
| goto yy20; |
| } |
| } |
| } else { |
| if(yych <= 'l'){ |
| if(yych <= 'b'){ |
| if(yych <= '`') goto yy21; |
| if(yych >= 'b') goto yy14; |
| goto yy12; |
| } else { |
| if(yych == 'j') goto yy15; |
| if(yych <= 'k') goto yy21; |
| goto yy16; |
| } |
| } else { |
| if(yych <= 'q'){ |
| if(yych == 'n') goto yy18; |
| goto yy21; |
| } else { |
| if(yych <= 'r') goto yy19; |
| if(yych <= 's') goto yy17; |
| if(yych <= 't') goto yy20; |
| goto yy21; |
| } |
| } |
| } |
| yy12: yych = *++YYCURSOR; |
| if(yych <= 'N'){ |
| if(yych == 'D') goto yy88; |
| if(yych <= 'M') goto yy22; |
| goto yy89; |
| } else { |
| if(yych <= 'd'){ |
| if(yych <= 'c') goto yy22; |
| goto yy88; |
| } else { |
| if(yych == 'n') goto yy89; |
| goto yy22; |
| } |
| } |
| yy13: |
| #line 435 "./modules/arch/lc3b/lc3bid.re" |
| { |
| return YASM_ARCH_NOTINSNPREFIX; |
| } |
| #line 510 "lc3bid.c" |
| yy14: yych = *++YYCURSOR; |
| if(yych == 'R') goto yy72; |
| if(yych == 'r') goto yy72; |
| goto yy22; |
| yy15: yych = *++YYCURSOR; |
| if(yych <= 'S'){ |
| if(yych == 'M') goto yy66; |
| if(yych <= 'R') goto yy22; |
| goto yy67; |
| } else { |
| if(yych <= 'm'){ |
| if(yych <= 'l') goto yy22; |
| goto yy66; |
| } else { |
| if(yych == 's') goto yy67; |
| goto yy22; |
| } |
| } |
| yy16: yych = *++YYCURSOR; |
| if(yych <= 'S'){ |
| if(yych <= 'D'){ |
| if(yych <= 'C') goto yy22; |
| goto yy53; |
| } else { |
| if(yych <= 'E') goto yy55; |
| if(yych <= 'R') goto yy22; |
| goto yy56; |
| } |
| } else { |
| if(yych <= 'e'){ |
| if(yych <= 'c') goto yy22; |
| if(yych <= 'd') goto yy53; |
| goto yy55; |
| } else { |
| if(yych == 's') goto yy56; |
| goto yy22; |
| } |
| } |
| yy17: yych = *++YYCURSOR; |
| if(yych == 'T') goto yy47; |
| if(yych == 't') goto yy47; |
| goto yy22; |
| yy18: yych = *++YYCURSOR; |
| if(yych == 'O') goto yy42; |
| if(yych == 'o') goto yy42; |
| goto yy22; |
| yy19: yych = *++YYCURSOR; |
| if(yych <= 'T'){ |
| if(yych <= 'E'){ |
| if(yych <= 'D') goto yy22; |
| goto yy29; |
| } else { |
| if(yych <= 'R') goto yy22; |
| if(yych <= 'S') goto yy30; |
| goto yy31; |
| } |
| } else { |
| if(yych <= 'r'){ |
| if(yych == 'e') goto yy29; |
| goto yy22; |
| } else { |
| if(yych <= 's') goto yy30; |
| if(yych <= 't') goto yy31; |
| goto yy22; |
| } |
| } |
| yy20: yych = *++YYCURSOR; |
| if(yych == 'R') goto yy25; |
| if(yych == 'r') goto yy25; |
| goto yy22; |
| yy21: ++YYCURSOR; |
| if(YYLIMIT == YYCURSOR) YYFILL(1); |
| yych = *YYCURSOR; |
| goto yy22; |
| yy22: if(yych <= '\000') goto yy13; |
| goto yy21; |
| yy23: yych = *++YYCURSOR; |
| goto yy24; |
| yy24: |
| #line 438 "./modules/arch/lc3b/lc3bid.re" |
| { |
| return YASM_ARCH_NOTINSNPREFIX; |
| } |
| #line 594 "lc3bid.c" |
| yy25: yych = *++YYCURSOR; |
| if(yych == 'A') goto yy26; |
| if(yych != 'a') goto yy22; |
| goto yy26; |
| yy26: yych = *++YYCURSOR; |
| if(yych == 'P') goto yy27; |
| if(yych != 'p') goto yy22; |
| goto yy27; |
| yy27: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy28; |
| yy28: |
| #line 432 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(trap, 0); } |
| #line 609 "lc3bid.c" |
| yy29: yych = *++YYCURSOR; |
| if(yych == 'T') goto yy40; |
| if(yych == 't') goto yy40; |
| goto yy22; |
| yy30: yych = *++YYCURSOR; |
| if(yych == 'H') goto yy34; |
| if(yych == 'h') goto yy34; |
| goto yy22; |
| yy31: yych = *++YYCURSOR; |
| if(yych == 'I') goto yy32; |
| if(yych != 'i') goto yy22; |
| goto yy32; |
| yy32: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy33; |
| yy33: |
| #line 425 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(nooperand, 0x80); } |
| #line 628 "lc3bid.c" |
| yy34: yych = *++YYCURSOR; |
| if(yych == 'F') goto yy35; |
| if(yych != 'f') goto yy22; |
| goto yy35; |
| yy35: yych = *++YYCURSOR; |
| if(yych <= 'L'){ |
| if(yych == 'A') goto yy38; |
| if(yych <= 'K') goto yy22; |
| goto yy36; |
| } else { |
| if(yych <= 'a'){ |
| if(yych <= '`') goto yy22; |
| goto yy38; |
| } else { |
| if(yych != 'l') goto yy22; |
| goto yy36; |
| } |
| } |
| yy36: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy37; |
| yy37: |
| #line 429 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(shift, 0x10); } |
| #line 653 "lc3bid.c" |
| yy38: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy39; |
| yy39: |
| #line 430 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(shift, 0x30); } |
| #line 660 "lc3bid.c" |
| yy40: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy41; |
| yy41: |
| #line 424 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(nooperand, 0xCE); } |
| #line 667 "lc3bid.c" |
| yy42: yych = *++YYCURSOR; |
| if(yych <= 'T'){ |
| if(yych == 'P') goto yy45; |
| if(yych <= 'S') goto yy22; |
| goto yy43; |
| } else { |
| if(yych <= 'p'){ |
| if(yych <= 'o') goto yy22; |
| goto yy45; |
| } else { |
| if(yych != 't') goto yy22; |
| goto yy43; |
| } |
| } |
| yy43: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy44; |
| yy44: |
| #line 422 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(not, 0); } |
| #line 688 "lc3bid.c" |
| yy45: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy46; |
| yy46: |
| #line 426 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(nooperand, 0); } |
| #line 695 "lc3bid.c" |
| yy47: yych = *++YYCURSOR; |
| if(yych <= 'I'){ |
| if(yych <= 'A'){ |
| if(yych >= '\001') goto yy21; |
| goto yy48; |
| } else { |
| if(yych <= 'B') goto yy51; |
| if(yych <= 'H') goto yy21; |
| goto yy49; |
| } |
| } else { |
| if(yych <= 'b'){ |
| if(yych <= 'a') goto yy21; |
| goto yy51; |
| } else { |
| if(yych == 'i') goto yy49; |
| goto yy21; |
| } |
| } |
| yy48: |
| #line 416 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldst, 0x30); } |
| #line 718 "lc3bid.c" |
| yy49: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy50; |
| yy50: |
| #line 417 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldst, 0xB0); } |
| #line 725 "lc3bid.c" |
| yy51: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy52; |
| yy52: |
| #line 420 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldstb, 0x70); } |
| #line 732 "lc3bid.c" |
| yy53: yych = *++YYCURSOR; |
| if(yych <= 'I'){ |
| if(yych <= 'A'){ |
| if(yych >= '\001') goto yy21; |
| goto yy54; |
| } else { |
| if(yych <= 'B') goto yy64; |
| if(yych <= 'H') goto yy21; |
| goto yy62; |
| } |
| } else { |
| if(yych <= 'b'){ |
| if(yych <= 'a') goto yy21; |
| goto yy64; |
| } else { |
| if(yych == 'i') goto yy62; |
| goto yy21; |
| } |
| } |
| yy54: |
| #line 414 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldst, 0x20); } |
| #line 755 "lc3bid.c" |
| yy55: yych = *++YYCURSOR; |
| if(yych == 'A') goto yy60; |
| if(yych == 'a') goto yy60; |
| goto yy22; |
| yy56: yych = *++YYCURSOR; |
| if(yych == 'H') goto yy57; |
| if(yych != 'h') goto yy22; |
| goto yy57; |
| yy57: yych = *++YYCURSOR; |
| if(yych == 'F') goto yy58; |
| if(yych != 'f') goto yy22; |
| goto yy58; |
| yy58: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy59; |
| yy59: |
| #line 428 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(shift, 0x00); } |
| #line 774 "lc3bid.c" |
| yy60: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy61; |
| yy61: |
| #line 412 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(lea, 0); } |
| #line 781 "lc3bid.c" |
| yy62: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy63; |
| yy63: |
| #line 415 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldst, 0xA0); } |
| #line 788 "lc3bid.c" |
| yy64: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy65; |
| yy65: |
| #line 419 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(ldstb, 0x60); } |
| #line 795 "lc3bid.c" |
| yy66: yych = *++YYCURSOR; |
| if(yych == 'P') goto yy70; |
| if(yych == 'p') goto yy70; |
| goto yy22; |
| yy67: yych = *++YYCURSOR; |
| if(yych == 'R') goto yy68; |
| if(yych != 'r') goto yy22; |
| goto yy68; |
| yy68: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy69; |
| yy69: |
| #line 408 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x40); } |
| #line 810 "lc3bid.c" |
| yy70: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy71; |
| yy71: |
| #line 410 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(jmp, 0); } |
| #line 817 "lc3bid.c" |
| yy72: yych = *++YYCURSOR; |
| if(yych <= 'Z'){ |
| if(yych <= 'N'){ |
| if(yych <= '\000') goto yy73; |
| if(yych <= 'M') goto yy21; |
| goto yy74; |
| } else { |
| if(yych == 'P') goto yy78; |
| if(yych <= 'Y') goto yy21; |
| goto yy76; |
| } |
| } else { |
| if(yych <= 'o'){ |
| if(yych == 'n') goto yy74; |
| goto yy21; |
| } else { |
| if(yych <= 'p') goto yy78; |
| if(yych == 'z') goto yy76; |
| goto yy21; |
| } |
| } |
| yy73: |
| #line 400 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x00); } |
| #line 842 "lc3bid.c" |
| yy74: yych = *++YYCURSOR; |
| if(yych <= 'Z'){ |
| if(yych <= 'O'){ |
| if(yych >= '\001') goto yy21; |
| goto yy75; |
| } else { |
| if(yych <= 'P') goto yy82; |
| if(yych <= 'Y') goto yy21; |
| goto yy84; |
| } |
| } else { |
| if(yych <= 'p'){ |
| if(yych <= 'o') goto yy21; |
| goto yy82; |
| } else { |
| if(yych == 'z') goto yy84; |
| goto yy21; |
| } |
| } |
| yy75: |
| #line 401 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x08); } |
| #line 865 "lc3bid.c" |
| yy76: yych = *++YYCURSOR; |
| if(yych <= 'P'){ |
| if(yych <= '\000') goto yy77; |
| if(yych <= 'O') goto yy21; |
| goto yy80; |
| } else { |
| if(yych == 'p') goto yy80; |
| goto yy21; |
| } |
| yy77: |
| #line 402 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x04); } |
| #line 878 "lc3bid.c" |
| yy78: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy79; |
| yy79: |
| #line 403 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x02); } |
| #line 885 "lc3bid.c" |
| yy80: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy81; |
| yy81: |
| #line 406 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x06); } |
| #line 892 "lc3bid.c" |
| yy82: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy83; |
| yy83: |
| #line 405 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x0A); } |
| #line 899 "lc3bid.c" |
| yy84: yych = *++YYCURSOR; |
| if(yych <= 'P'){ |
| if(yych <= '\000') goto yy85; |
| if(yych <= 'O') goto yy21; |
| goto yy86; |
| } else { |
| if(yych == 'p') goto yy86; |
| goto yy21; |
| } |
| yy85: |
| #line 404 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x0C); } |
| #line 912 "lc3bid.c" |
| yy86: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy87; |
| yy87: |
| #line 407 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(br, 0x0E); } |
| #line 919 "lc3bid.c" |
| yy88: yych = *++YYCURSOR; |
| if(yych == 'D') goto yy92; |
| if(yych == 'd') goto yy92; |
| goto yy22; |
| yy89: yych = *++YYCURSOR; |
| if(yych == 'D') goto yy90; |
| if(yych != 'd') goto yy22; |
| goto yy90; |
| yy90: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy91; |
| yy91: |
| #line 398 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(addand, 0x40); } |
| #line 934 "lc3bid.c" |
| yy92: yych = *++YYCURSOR; |
| if(yych >= '\001') goto yy21; |
| goto yy93; |
| yy93: |
| #line 397 "./modules/arch/lc3b/lc3bid.re" |
| { RET_INSN(addand, 0x00); } |
| #line 941 "lc3bid.c" |
| } |
| #line 441 "./modules/arch/lc3b/lc3bid.re" |
| |
| |
| done: |
| id_insn = yasm_xmalloc(sizeof(lc3b_id_insn)); |
| yasm_insn_initialize(&id_insn->insn); |
| id_insn->group = group; |
| id_insn->mod_data = mod; |
| id_insn->num_info = nelems; |
| *bc = yasm_bc_create_common(&lc3b_id_insn_callback, id_insn, line); |
| return YASM_ARCH_INSN; |
| } |
| |
| static void |
| lc3b_id_insn_destroy(void *contents) |
| { |
| lc3b_id_insn *id_insn = (lc3b_id_insn *)contents; |
| yasm_insn_delete(&id_insn->insn, yasm_lc3b__ea_destroy); |
| yasm_xfree(contents); |
| } |
| |
| static void |
| lc3b_id_insn_print(const void *contents, FILE *f, int indent_level) |
| { |
| const lc3b_id_insn *id_insn = (const lc3b_id_insn *)contents; |
| yasm_insn_print(&id_insn->insn, f, indent_level); |
| /*TODO*/ |
| } |
| |
| /*@only@*/ yasm_bytecode * |
| yasm_lc3b__create_empty_insn(yasm_arch *arch, unsigned long line) |
| { |
| lc3b_id_insn *id_insn = yasm_xmalloc(sizeof(lc3b_id_insn)); |
| |
| yasm_insn_initialize(&id_insn->insn); |
| id_insn->group = empty_insn; |
| id_insn->mod_data = 0; |
| id_insn->num_info = NELEMS(empty_insn); |
| |
| return yasm_bc_create_common(&lc3b_id_insn_callback, id_insn, line); |
| } |