diff -r af9fdb3fc199 gas/ChangeLog.ggx --- a/gas/ChangeLog.ggx Wed Mar 19 09:03:59 2008 -0700 +++ b/gas/ChangeLog.ggx Thu Mar 20 05:59:22 2008 -0700 @@ -2,6 +2,7 @@ 2008-03-19 Anthony Green diff -r af9fdb3fc199 gas/config/tc-ggx.c --- a/gas/config/tc-ggx.c Wed Mar 19 09:03:59 2008 -0700 +++ b/gas/config/tc-ggx.c Thu Mar 20 05:59:22 2008 -0700 @@ -375,6 +375,114 @@ md_assemble (char *str) iword += (a << 6); } break; + case GGX_F1_ABi4: + iword = opcode->opcode << 9; + while (ISSPACE (*op_end)) + op_end++; + { + expressionS arg; + char *offset; + int a, b; + + a = parse_register_operand (&op_end); + while (ISSPACE (*op_end)) + op_end++; + + if (*op_end != ',') + { + as_bad ("expecting comma delimited operands"); + ignore_rest_of_line (); + return; + } + op_end++; + + op_end = parse_exp_save_ilp (op_end, &arg); + offset = frag_more (4); + fix_new_exp (frag_now, + (offset - frag_now->fr_literal), + 4, + &arg, + 0, + BFD_RELOC_32); + + if (*op_end != '(') + { + as_bad ("expecting indirect register `($rX)'"); + ignore_rest_of_line (); + return; + } + op_end++; + b = parse_register_operand (&op_end); + if (*op_end != ')') + { + as_bad ("missing closing parenthesis"); + ignore_rest_of_line (); + return; + } + op_end++; + + while (ISSPACE (*op_end)) + op_end++; + if (*op_end != 0) + as_warn ("extra stuff on line ignored"); + + iword += (a << 6) + (b << 3); + } + break; + case GGX_F1_AiB4: + iword = opcode->opcode << 9; + while (ISSPACE (*op_end)) + op_end++; + { + expressionS arg; + char *offset; + int a, b; + + op_end = parse_exp_save_ilp (op_end, &arg); + offset = frag_more (4); + fix_new_exp (frag_now, + (offset - frag_now->fr_literal), + 4, + &arg, + 0, + BFD_RELOC_32); + + if (*op_end != '(') + { + as_bad ("expecting indirect register `($rX)'"); + ignore_rest_of_line (); + return; + } + op_end++; + a = parse_register_operand (&op_end); + if (*op_end != ')') + { + as_bad ("missing closing parenthesis"); + ignore_rest_of_line (); + return; + } + op_end++; + + if (*op_end != ',') + { + as_bad ("expecting comma delimited operands"); + ignore_rest_of_line (); + return; + } + op_end++; + + b = parse_register_operand (&op_end); + while (ISSPACE (*op_end)) + op_end++; + + while (ISSPACE (*op_end)) + op_end++; + if (*op_end != 0) + as_warn ("extra stuff on line ignored"); + + iword += (a << 6) + (b << 3); + } + break; case GGX_F2_NARG: iword = opcode->opcode << 12; while (ISSPACE (*op_end)) diff -r af9fdb3fc199 include/opcode/ChangeLog.ggx --- a/include/opcode/ChangeLog.ggx Wed Mar 19 09:03:59 2008 -0700 +++ b/include/opcode/ChangeLog.ggx Thu Mar 20 05:59:22 2008 -0700 @@ -1,6 +1,7 @@ 2008-03-19 Anthony Green * ggx.h (GGX_F1_AiB, GGX_F1_ABi, GGX_F1_4A): Define. + (GGX_F1_ABi4, GGX_F1_AiB4): Define. 2008-03-16 Anthony Green diff -r af9fdb3fc199 include/opcode/ggx.h --- a/include/opcode/ggx.h Wed Mar 19 09:03:59 2008 -0700 +++ b/include/opcode/ggx.h Thu Mar 20 05:59:22 2008 -0700 @@ -26,9 +26,11 @@ 02110-1301, USA. */ Some use A, B and C registers (GGX_F1_ABC) Some use A and consume a 4 byte immediate value (GGX_F1_A4) Some use just a 4 byte immediate value (GGX_F1_4) - Some use Y and an indirect X (GGX_F1_AiB) - Some use X and an indirect Y (GGX_F1_ABi) + Some use B and an indirect A (GGX_F1_AiB) + Some use A and an indirect B (GGX_F1_ABi) Some consume a 4 byte immediate value and use X (GGX_F1_4A) + Some use B and an indirect A plus 4 bytes (GGX_F1_AiB4) + Some use A and an indirect B plus 4 bytes (GGX_F1_ABi4) Form 2 instructions also come in different flavors: @@ -45,6 +47,8 @@ 02110-1301, USA. */ #define GGX_F1_AiB 0x106 #define GGX_F1_ABi 0x107 #define GGX_F1_4A 0x108 +#define GGX_F1_AiB4 0x109 +#define GGX_F1_ABi4 0x10a #define GGX_F2_NARG 0x200 #define GGX_F2_12V 0x201 diff -r af9fdb3fc199 opcodes/ChangeLog.ggx --- a/opcodes/ChangeLog.ggx Wed Mar 19 09:03:59 2008 -0700 +++ b/opcodes/ChangeLog.ggx Thu Mar 20 05:59:22 2008 -0700 @@ -2,7 +2,10 @@ 2008-03-19 Anthony Green diff -r af9fdb3fc199 opcodes/ggx-dis.c --- a/opcodes/ggx-dis.c Wed Mar 19 09:03:59 2008 -0700 +++ b/opcodes/ggx-dis.c Thu Mar 20 05:59:22 2008 -0700 @@ -114,6 +114,33 @@ print_insn_ggx (bfd_vma addr, struct dis length = 6; } break; + case GGX_F1_AiB4: + { + unsigned imm; + if ((status = info->read_memory_func (addr+2, buffer, 4, info))) + goto fail; + imm = bfd_getb32 (buffer); + fpr (stream, "%s\t0x%x(%s), %s", opcode->name, + imm, + reg_names[OP_A(iword)], + reg_names[OP_B(iword)]); + length = 6; + } + break; + case GGX_F1_ABi4: + { + unsigned imm; + if ((status = info->read_memory_func (addr+2, buffer, 4, info))) + goto fail; + imm = bfd_getb32 (buffer); + fpr (stream, "%s\t%s, 0x%x(%s)", + opcode->name, + reg_names[OP_A(iword)], + imm, + reg_names[OP_B(iword)]); + length = 6; + } + break; default: abort(); } diff -r af9fdb3fc199 opcodes/ggx-opc.c --- a/opcodes/ggx-opc.c Wed Mar 19 09:03:59 2008 -0700 +++ b/opcodes/ggx-opc.c Thu Mar 20 05:59:22 2008 -0700 @@ -58,8 +58,8 @@ const ggx_opc_info_t ggx_form1_opc_info[ { 0x08, GGX_F1_4A, "sta.l" }, { 0x09, GGX_F1_ABi, "ld.l" }, { 0x0a, GGX_F1_AiB, "st.l" }, - { 0x0b, GGX_F1_NARG, "bad" }, - { 0x0c, GGX_F1_NARG, "bad" }, + { 0x0b, GGX_F1_ABi4, "ldo.l" }, + { 0x0c, GGX_F1_AiB4, "sto.l" }, { 0x0d, GGX_F1_NARG, "bad" }, { 0x0e, GGX_F1_NARG, "bad" }, { 0x0f, GGX_F1_NARG, "bad" }, diff -r af9fdb3fc199 sim/ggx/interp.c --- a/sim/ggx/interp.c Wed Mar 19 09:03:59 2008 -0700 +++ b/sim/ggx/interp.c Thu Mar 20 05:59:22 2008 -0700 @@ -479,6 +479,40 @@ sim_resume (sd, step, siggnal) reg_names[dest], cpu.asregs.regs[dest]); } break; + case 0x0b: /* ldo.l */ + { + unsigned int addr = EXTRACT_WORD(&memory[pc+2]); + int a = (inst >> 6) & 0x7; + int b = (inst >> 3) & 0x7; + addr += cpu.asregs.regs[b]; + cpu.asregs.regs[a] = rlat(addr); + pc += 4; + if (tracing) + callback->printf_filtered (callback, + "# 0x%08x: loading word (0x%x) from 0x%x into %s\n", + opc, + cpu.asregs.regs[a], + addr, + reg_names[a]); + } + break; + case 0x0c: /* sto.w */ + { + unsigned int addr = EXTRACT_WORD(&memory[pc+2]); + int a = (inst >> 6) & 0x7; + int b = (inst >> 3) & 0x7; + addr += cpu.asregs.regs[a]; + wlat(addr, cpu.asregs.regs[b]); + pc += 4; + if (tracing) + callback->printf_filtered (callback, + "# 0x%08x: writing word (0x%x) from %s to 0x%x\n", + opc, + cpu.asregs.regs[b], + reg_names[b], + addr); + } + break; default: cpu.asregs.exception = SIGILL; break;