From f610b17c8dd279232337eb576658970e589f7a1d Mon Sep 17 00:00:00 2001 From: dfr Date: Tue, 10 Oct 2000 14:57:10 +0000 Subject: * Add rudimentary DDB support (no kgdb, no backtrace, no single step). * Track recent changes to SWI code. * Allocate RIDs for pmaps (untested). * Implement assembler version of cpu_switch - its cleaner that way. --- sys/ia64/conf/GENERIC | 2 + sys/ia64/ia64/db_disasm.c | 2874 +++++++++++++++++++++++++++++++++++++++++ sys/ia64/ia64/db_interface.c | 534 ++++++++ sys/ia64/ia64/db_trace.c | 42 + sys/ia64/ia64/genassym.c | 1 + sys/ia64/ia64/ia64-gdbstub.c | 588 +++++++++ sys/ia64/ia64/ipl_funcs.c | 136 +- sys/ia64/ia64/machdep.c | 2 +- sys/ia64/ia64/mp_machdep.c | 2 - sys/ia64/ia64/pmap.c | 341 +++-- sys/ia64/ia64/swtch.s | 131 +- sys/ia64/ia64/synch_machdep.c | 17 - sys/ia64/ia64/vm_machdep.c | 7 + sys/ia64/include/atomic.h | 23 + sys/ia64/include/cpu.h | 3 +- sys/ia64/include/db_machdep.h | 28 +- sys/ia64/include/globaldata.h | 1 + sys/ia64/include/ia64_cpu.h | 36 + sys/ia64/include/inst.h | 1168 +++++++++++++++++ sys/ia64/include/ipl.h | 79 -- sys/ia64/include/pcpu.h | 1 + sys/ia64/include/pmap.h | 7 +- 22 files changed, 5595 insertions(+), 428 deletions(-) create mode 100644 sys/ia64/ia64/db_disasm.c create mode 100644 sys/ia64/ia64/db_interface.c create mode 100644 sys/ia64/ia64/db_trace.c create mode 100644 sys/ia64/ia64/ia64-gdbstub.c create mode 100644 sys/ia64/include/inst.h (limited to 'sys') diff --git a/sys/ia64/conf/GENERIC b/sys/ia64/conf/GENERIC index c5f9724..7ba5107 100644 --- a/sys/ia64/conf/GENERIC +++ b/sys/ia64/conf/GENERIC @@ -163,3 +163,5 @@ device ums # Mouse device aue # ADMtek USB ethernet device cue # CATC USB ethernet device kue # Kawasaki LSI USB ethernet + +options DDB diff --git a/sys/ia64/ia64/db_disasm.c b/sys/ia64/ia64/db_disasm.c new file mode 100644 index 0000000..f9139e5 --- /dev/null +++ b/sys/ia64/ia64/db_disasm.c @@ -0,0 +1,2874 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * 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 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 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define sign_extend(imm, w) (((int64_t)(imm) << (64 - (w))) >> (64 - (w))) + +struct ia64_bundle { + u_int64_t slot[3]; + int template; +}; + +typedef void (*ia64_print_slot)(db_addr_t loc, u_int64_t slot, boolean_t showregs); + +static void ia64_print_M(db_addr_t, u_int64_t, boolean_t); +static void ia64_print_I(db_addr_t, u_int64_t, boolean_t); +static void ia64_print_X(db_addr_t, u_int64_t, boolean_t); +static void ia64_print_B(db_addr_t, u_int64_t, boolean_t); +static void ia64_print_F(db_addr_t, u_int64_t, boolean_t); +static void ia64_print_bad(db_addr_t, u_int64_t, boolean_t); + +#define M ia64_print_M +#define I ia64_print_I +#define X ia64_print_X +#define B ia64_print_B +#define F ia64_print_F +#define _ ia64_print_bad + +/* + * Convert template+slot into a function to disassemble that slot. + */ +static ia64_print_slot prints[][3] = { + { M, I, I }, /* 00 */ + { M, I, I }, /* 01 */ + { M, I, I }, /* 02 */ + { M, I, I }, /* 03 */ + { M, _, X }, /* 04 */ + { M, _, X,}, /* 05 */ + { _, _, _ }, /* 06 */ + { _, _, _ }, /* 07 */ + { M, M, I }, /* 08 */ + { M, M, I }, /* 09 */ + { M, M, I }, /* 0a */ + { M, M, I }, /* 0b */ + { M, F, I }, /* 0c */ + { M, F, I }, /* 0d */ + { M, M, F }, /* 0e */ + { M, M, F }, /* 0f */ + { M, I, B }, /* 10 */ + { M, I, B }, /* 11 */ + { M, B, B }, /* 12 */ + { M, B, B }, /* 13 */ + { _, _, _ }, /* 14 */ + { _, _, _ }, /* 15 */ + { B, B, B }, /* 16 */ + { B, B, B }, /* 17 */ + { M, M, B }, /* 18 */ + { M, M, B }, /* 19 */ + { _, _, _ }, /* 1a */ + { _, _, _ }, /* 1b */ + { M, F, B }, /* 1c */ + { M, F, B }, /* 1d */ + { _, _, _ }, /* 1e */ + { _, _, _ }, /* 1f */ +}; + +#undef M +#undef I +#undef X +#undef B +#undef F +#undef _ + +/* + * Nonzero if template+slot has a following stop + */ +static char stops[][3] = { + { 0, 0, 0 }, /* 00 */ + { 0, 0, 1 }, /* 01 */ + { 0, 1, 0 }, /* 02 */ + { 0, 1, 1 }, /* 03 */ + { 0, 0, 0 }, /* 04 */ + { 0, 0, 1 }, /* 05 */ + { 0, 0, 0 }, /* 06 */ + { 0, 0, 0 }, /* 07 */ + { 0, 0, 0 }, /* 08 */ + { 0, 0, 1 }, /* 09 */ + { 1, 0, 0 }, /* 0a */ + { 1, 0, 1 }, /* 0b */ + { 0, 0, 0 }, /* 0c */ + { 0, 0, 1 }, /* 0d */ + { 0, 0, 0 }, /* 0e */ + { 0, 0, 1 }, /* 0f */ + { 0, 0, 0 }, /* 10 */ + { 0, 0, 1 }, /* 11 */ + { 0, 0, 0 }, /* 12 */ + { 0, 0, 1 }, /* 13 */ + { 0, 0, 0 }, /* 14 */ + { 0, 0, 0 }, /* 15 */ + { 0, 0, 0 }, /* 16 */ + { 0, 0, 1 }, /* 17 */ + { 0, 0, 0 }, /* 18 */ + { 0, 0, 1 }, /* 19 */ + { 0, 0, 0 }, /* 1a */ + { 0, 0, 0 }, /* 1b */ + { 0, 0, 0 }, /* 1c */ + { 0, 0, 1 }, /* 1d */ + { 0, 0, 0 }, /* 1e */ + { 0, 0, 0 }, /* 1f */ +}; + +const char *register_names[] = { + "r0", "gp", "r2", "r3", + "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", + "sp", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", + "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", + "r28", "r29", "r30", "r31", + "r32", "r33", "r34", "r35", + "r36", "r37", "r38", "r39", + "r40", "r41", "r42", "r43", + "r44", "r45", "r46", "r47", + "r48", "r49", "r50", "r51", + "r52", "r53", "r54", "r55", + "r56", "r57", "r58", "r59", + "r60", "r61", "r62", "r63", + "r64", "r65", "r66", "r67", + "r68", "r69", "r70", "r71", + "r72", "r73", "r74", "r75", + "r76", "r77", "r78", "r79", + "r80", "r81", "r82", "r83", + "r84", "r85", "r86", "r87", + "r88", "r89", "r90", "r91", + "r92", "r93", "r94", "r95", + "r96", "r97", "r98", "r99", + "r100", "r101", "r102", "r103", + "r104", "r105", "r106", "r107", + "r108", "r109", "r110", "r111", + "r112", "r113", "r114", "r115", + "r116", "r117", "r118", "r119", + "r120", "r121", "r122", "r123", + "r124", "r125", "r126", "r127", +}; + +const char *branch_names[] = { + "rp", "b1", "b2", "b3", "b4", "b5", "b6", "b7" +}; + +const char *appreg_names[] = { + "ar0", "ar1", "ar2", "ar3", + "ar4", "ar5", "ar6", "ar7", + "ar8", "ar9", "ar10", "ar11", + "ar12", "ar13", "ar14", "ar15", + "ar16", "ar17", "ar18", "ar19", + "ar20", "ar21", "ar22", "ar23", + "ar24", "ar25", "ar26", "ar27", + "ar28", "ar29", "ar30", "ar31", + "ar32", "ar33", "ar34", "ar35", + "ar36", "ar37", "ar38", "ar39", + "ar40", "ar41", "ar42", "ar43", + "ar44", "ar45", "ar46", "ar47", + "ar48", "ar49", "ar50", "ar51", + "ar52", "ar53", "ar54", "ar55", + "ar56", "ar57", "ar58", "ar59", + "ar60", "ar61", "ar62", "ar63", + "ar64", "ar65", "ar66", "ar67", + "ar68", "ar69", "ar70", "ar71", + "ar72", "ar73", "ar74", "ar75", + "ar76", "ar77", "ar78", "ar79", + "ar80", "ar81", "ar82", "ar83", + "ar84", "ar85", "ar86", "ar87", + "ar88", "ar89", "ar90", "ar91", + "ar92", "ar93", "ar94", "ar95", + "ar96", "ar97", "ar98", "ar99", + "ar100","ar101","ar102","ar103", + "ar104","ar105","ar106","ar107", + "ar108","ar109","ar110","ar111", + "ar112","ar113","ar114","ar115", + "ar116","ar117","ar118","ar119", + "ar120","ar121","ar122","ar123", + "ar124","ar125","ar126","ar127", +}; + +const char *control_names[] = { + "cr0", "cr1", "cr2", "cr3", + "cr4", "cr5", "cr6", "cr7", + "cr8", "cr9", "cr10", "cr11", + "cr12", "cr13", "cr14", "cr15", + "cr16", "cr17", "cr18", "cr19", + "cr20", "cr21", "cr22", "cr23", + "cr24", "cr25", "cr26", "cr27", + "cr28", "cr29", "cr30", "cr31", + "cr32", "cr33", "cr34", "cr35", + "cr36", "cr37", "cr38", "cr39", + "cr40", "cr41", "cr42", "cr43", + "cr44", "cr45", "cr46", "cr47", + "cr48", "cr49", "cr50", "cr51", + "cr52", "cr53", "cr54", "cr55", + "cr56", "cr57", "cr58", "cr59", + "cr60", "cr61", "cr62", "cr63", + "cr64", "cr65", "cr66", "cr67", + "cr68", "cr69", "cr70", "cr71", + "cr72", "cr73", "cr74", "cr75", + "cr76", "cr77", "cr78", "cr79", + "cr80", "cr81", "cr82", "cr83", + "cr84", "cr85", "cr86", "cr87", + "cr88", "cr89", "cr90", "cr91", + "cr92", "cr93", "cr94", "cr95", + "cr96", "cr97", "cr98", "cr99", + "cr100","cr101","cr102","cr103", + "cr104","cr105","cr106","cr107", + "cr108","cr109","cr110","cr111", + "cr112","cr113","cr114","cr115", + "cr116","cr117","cr118","cr119", + "cr120","cr121","cr122","cr123", + "cr124","cr125","cr126","cr127", +}; + +static void +ia64_fetch_bundle(db_addr_t loc, struct ia64_bundle *bp) +{ + u_int64_t low, high; + + loc &= ~15; + + db_read_bytes(loc, 8, (caddr_t) &low); + db_read_bytes(loc+8, 8, (caddr_t) &high); + + bp->template = low & 0x1f; + bp->slot[0] = (low >> 5) & ((1L<<41) - 1); + bp->slot[1] = (low >> 46) | ((high & ((1L<<23) - 1)) << 18); + bp->slot[2] = (high >> 23); +} + +static void +ia64_print_ill(const char *name, u_int64_t ins, db_addr_t loc) +{ + db_printf("%s %lx", name, ins); +} + +static void +ia64_print_A1(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.A1.r1], + register_names[u.A1.r2], + register_names[u.A1.r3]); +} + +static void +ia64_print_A1_comma1(const char *name, u_int64_t ins, db_addr_t loc) +{ + ia64_print_A1(name, ins, loc); + db_printf(",1"); +} + +static void +ia64_print_A2(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d,%s", + name, + register_names[u.A2.r1], + register_names[u.A2.r2], + u.A2.ct2d + 1, + register_names[u.A2.r3]); +} + +static void +ia64_print_A3(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + u.ins = ins; + db_printf("%s %s=%ld,%s", + name, + register_names[u.A3.r1], + sign_extend((u.A3.s << 7) | u.A3.imm7b, 8), + register_names[u.A3.r3]); +} + +static void +ia64_print_A4(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%ld,%s", + name, + register_names[u.A4.r1], + sign_extend((u.A4.s << 13) | (u.A4.imm6d << 7) | u.A4.imm7b, 14), + register_names[u.A4.r3]); +} + +static void +ia64_print_A4_mov(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.A4.r1], + register_names[u.A4.r3]); +} + +static void +ia64_print_A5(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%ld,%s", + name, + register_names[u.A5.r1], + sign_extend((u.A5.s << 21) | (u.A5.imm5c << 16) + | (u.A5.imm9d << 7) | u.A5.imm7b, 22), + register_names[u.A5.r3]); +} + +static void +ia64_print_A6(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s p%d,p%d=%s,%s", + name, + u.A6.p1, + u.A6.p2, + register_names[u.A6.r2], + register_names[u.A6.r3]); +} + +static void +ia64_print_A7(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s p%d,p%d=r0,%s", + name, + u.A7.p1, + u.A7.p2, + register_names[u.A7.r3]); +} + +static void +ia64_print_A8(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s p%d,p%d=%ld,%s", + name, + u.A8.p1, + u.A8.p2, + sign_extend((u.A8.s << 7) | u.A8.imm7b, 8), + register_names[u.A8.r3]); +} + +static void +ia64_print_A9(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.A9.r1], + register_names[u.A9.r2], + register_names[u.A9.r3]); +} + +static void +ia64_print_A10(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d,%s", + name, + register_names[u.A10.r1], + register_names[u.A10.r2], + u.A10.ct2d + 1, + register_names[u.A10.r3]); +} + +static void +ia64_print_I1(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + static int count2[] = { 0, 7, 15, 16 }; + u.ins = ins; + db_printf("%s %s=%s,%s,%d", + name, + register_names[u.I1.r1], + register_names[u.I1.r2], + register_names[u.I1.r3], + count2[u.I1.ct2d]); +} + +static void +ia64_print_I2(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.I2.r1], + register_names[u.I2.r2], + register_names[u.I2.r3]); +} + +static void +ia64_print_I3(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + static const char *mbtype4[] = { + "@brcst", /* 0 */ + "@reserved", /* 1 */ + "@reserved", /* 2 */ + "@reserved", /* 3 */ + "@reserved", /* 4 */ + "@reserved", /* 5 */ + "@reserved", /* 6 */ + "@reserved", /* 7 */ + "@mix", /* 8 */ + "@shuf", /* 9 */ + "@alt", /* 10 */ + "@rev", /* 11 */ + "@reserved", /* 12 */ + "@reserved", /* 13 */ + "@reserved", /* 14 */ + "@reserved", /* 15 */ + }; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.I3.r1], + register_names[u.I3.r2], + mbtype4[u.I3.mbt4c]); +} + +static void +ia64_print_I4(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d", + name, + register_names[u.I4.r1], + register_names[u.I4.r2], + u.I4.mht8c); +} + +static void +ia64_print_I5(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.I5.r1], + register_names[u.I5.r3], + register_names[u.I5.r2]); +} + +static void +ia64_print_I6(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d", + name, + register_names[u.I6.r1], + register_names[u.I6.r3], + u.I6.count5b); +} + +static void +ia64_print_I7(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.I7.r1], + register_names[u.I7.r2], + register_names[u.I7.r3]); +} + +static void +ia64_print_I8(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d", + name, + register_names[u.I8.r1], + register_names[u.I8.r2], + 31 - u.I8.count5c); +} + +static void +ia64_print_I9(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.I9.r1], + register_names[u.I9.r3]); +} + +static void +ia64_print_I10(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s,%d", + name, + register_names[u.I10.r1], + register_names[u.I10.r2], + register_names[u.I10.r3], + u.I10.count6d); +} + +static void +ia64_print_I11(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d,%d", + name, + register_names[u.I11.r1], + register_names[u.I11.r3], + u.I11.pos6b, + u.I11.len6d + 1); +} + +static void +ia64_print_I12(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d,%d", + name, + register_names[u.I12.r1], + register_names[u.I12.r2], + 63 - u.I12.cpos6c, + u.I12.len6d + 1); +} + +static void +ia64_print_I13(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%ld,%d,%d", + name, + register_names[u.I13.r1], + sign_extend((u.I13.s << 7) | u.I13.imm7b, 8), + 63 - u.I13.cpos6c, + u.I13.len6d + 1); +} + +static void +ia64_print_I14(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%ld,%s,%d,%d", + name, + register_names[u.I14.r1], + sign_extend(u.I14.s, 1), + register_names[u.I14.r3], + 63 - u.I14.cpos6b, + u.I14.len6d + 1); +} + +static void +ia64_print_I15(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s,%d,%d", + name, + register_names[u.I15.r1], + register_names[u.I15.r2], + register_names[u.I15.r3], + 63 - u.I15.cpos6d, + u.I15.len4d + 1); +} + +static void +ia64_print_I16(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s p%d,p%d=%s,%d", + name, + u.I16.p1, + u.I16.p2, + register_names[u.I16.r3], + u.I16.pos6b); +} + +static void +ia64_print_I17(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s p%d,p%d=%s", + name, + u.I17.p1, + u.I17.p2, + register_names[u.I17.r3]); +} + +static void +ia64_print_I19(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %x", + name, + (u.I19.i << 20) | u.I19.imm20a); +} + +static void +ia64_print_I20(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s,", + name, + register_names[u.I20.r2]); + db_printsym((loc & ~15) + (sign_extend((u.I20.s << 20) + | (u.I20.imm13c << 7) + | u.I20.imm7a, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_I21(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + static const char *ih[] = { "", ".imp" }; + static const char *wh[] = { ".sptk", "", ".dptk", ".ill" }; + static const char *ret[] = { "", ".ret" }; + u.ins = ins; + + db_printf("%s%s%s%s %s=%s", + name, + ret[u.I21.x], + wh[u.I21.wh], + ih[u.I21.ih], + branch_names[u.I21.b1], + register_names[u.I21.r2]); + if (u.I21.timm9c) + db_printf(",%lx", + (loc & ~15) + (sign_extend(u.I21.timm9c, 9) << 4)); +} + +static void +ia64_print_I22(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.I22.r1], + register_names[u.I22.b2]); +} + +static void +ia64_print_I23(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s pr=%s,0x%lx", + name, + register_names[u.I23.r2], + sign_extend((u.I23.s << 16) + | (u.I23.mask8c << 8) + | (u.I23.mask7a << 1), 17)); +} + +static void +ia64_print_I24(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s pr.rot=%lx", + name, + sign_extend(((u_int64_t) u.I24.s << 43) + | (u.I24.imm27a << 16), 44)); +} + +static void +ia64_print_I25(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + if (u.I25.x6 == 0x30) + db_printf("%s %s=ip", + name, + register_names[u.I25.r1]); + else + db_printf("%s %s=pr", + name, + register_names[u.I25.r1]); +} + +static void +ia64_print_I26(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + appreg_names[u.I26.ar3], + register_names[u.I26.r2]); +} + +static void +ia64_print_I27(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%lx", + name, + appreg_names[u.I27.ar3], + sign_extend((u.I27.s << 7) | u.I27.imm7b, 8)); +} + +static void +ia64_print_I28(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.I28.r1], + appreg_names[u.I28.ar3]); +} + +static void +ia64_print_I29(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.I29.r1], + register_names[u.I29.r3]); +} + +static void +ia64_print_M1(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=[%s]", + name, + register_names[u.M1.r1], + register_names[u.M1.r3]); +} + +static void +ia64_print_M2(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=[%s],%s", + name, + register_names[u.M2.r1], + register_names[u.M2.r3], + register_names[u.M2.r2]); +} + +static void +ia64_print_M3(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=[%s],%ld", + name, + register_names[u.M3.r1], + register_names[u.M3.r3], + sign_extend((u.M3.s << 8) + | (u.M3.i << 7) + | u.M3.imm7b, 9)); +} + +static void +ia64_print_M4(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s]=%s", + name, + register_names[u.M4.r3], + register_names[u.M4.r2]); +} + +static void +ia64_print_M5(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s]=%s,%ld", + name, + register_names[u.M5.r3], + register_names[u.M5.r2], + sign_extend((u.M5.s << 8) + | (u.M5.i << 7) + | u.M5.imm7a, 9)); +} + +static void +ia64_print_M6(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=[%s]", + name, + u.M6.f1, + register_names[u.M6.r3]); +} + +static void +ia64_print_M7(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=[%s],%s", + name, + u.M7.f1, + register_names[u.M7.r3], + register_names[u.M7.r2]); +} + +static void +ia64_print_M8(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=[%s],%ld", + name, + u.M8.f1, + register_names[u.M8.r3], + sign_extend((u.M8.s << 8) + | (u.M8.i << 7) + | u.M8.imm7b, 9)); +} + +static void +ia64_print_M9(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s]=f%d", + name, + register_names[u.M9.r3], + u.M9.f2); +} + +static void +ia64_print_M10(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s]=f%d,%ld", + name, + register_names[u.M10.r3], + u.M10.f2, + sign_extend((u.M10.s << 8) + | (u.M10.i << 7) + | u.M10.imm7a, 9)); +} + +static void +ia64_print_M11(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d,f%d=[%s]", + name, + u.M11.f1, + u.M11.f2, + register_names[u.M11.r3]); +} + +static void +ia64_print_M12(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + int imm; + u.ins = ins; + if ((u.M12.x6 & 3) == 2) + imm = 8; + else + imm = 16; + db_printf("%s f%d,f%d=[%s],%d", + name, + u.M12.f1, + u.M12.f2, + register_names[u.M12.r3], + imm); +} + +static void +ia64_print_M13(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s]", + name, + register_names[u.M14.r3]); +} + +static void +ia64_print_M14(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s],%s", + name, + register_names[u.M14.r3], + register_names[u.M14.r2]); +} + +static void +ia64_print_M15(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s [%s],%ld", + name, + register_names[u.M15.r3], + sign_extend((u.M15.s << 8) + | (u.M15.i << 7) + | u.M15.imm7b, 9)); +} + +static void +ia64_print_M16(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + if (u.M16.x6 < 0x08) + db_printf("%s %s=[%s],%s,ar.ccv", + name, + register_names[u.M16.r1], + register_names[u.M16.r3], + register_names[u.M16.r2]); + else + db_printf("%s %s=[%s],%s", + name, + register_names[u.M16.r1], + register_names[u.M16.r3], + register_names[u.M16.r2]); +} + +static void +ia64_print_M17(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=[%s],%ld", + name, + register_names[u.M17.r1], + register_names[u.M17.r3], + sign_extend((u.M17.s << 2) | u.M17.i2b, 3)); +} + +static void +ia64_print_M18(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=%s", + name, + u.M18.f1, + register_names[u.M18.r2]); +} + +static void +ia64_print_M19(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=f%d", + name, + register_names[u.M19.r1], + u.M19.f2); +} + +static void +ia64_print_M20(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s,", + name, + register_names[u.M20.r2]); + db_printsym((loc & ~15) + (sign_extend((u.M20.s << 20) + | (u.M20.imm13c << 7) + | u.M20.imm7a, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_M21(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d,", + name, + u.M21.f2); + db_printsym((loc & ~15) + (sign_extend((u.M21.s << 20) + | (u.M21.imm13c << 7) + | u.M21.imm7a, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_M22(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s,", + name, + register_names[u.M22.r1]); + db_printsym((loc & ~15) + (sign_extend((u.M22.s << 20) + | u.M22.imm20b, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_M23(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d,", + name, + u.M23.f1); + db_printsym((loc & ~15) + (sign_extend((u.M23.s << 20) + | u.M23.imm20b, 21) << 4), + DB_STGY_PROC); +} + +/* Also M25 */ +static void +ia64_print_M24(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s", name); +} + +static void +ia64_print_M26(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s", + name, + register_names[u.M26.r1]); +} + +static void +ia64_print_M27(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d", + name, + u.M27.f1); +} + +static void +ia64_print_M28(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s", + name, + register_names[u.M28.r3]); +} + +static void +ia64_print_M29(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + appreg_names[u.M29.ar3], + register_names[u.M29.r2]); +} + +static void +ia64_print_M30(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%ld", + name, + appreg_names[u.M30.ar3], + sign_extend((u.M30.s << 7) | u.M30.imm7b, 8)); +} + +static void +ia64_print_M31(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.M31.r1], + appreg_names[u.M31.ar3]); +} + +static void +ia64_print_M32(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + control_names[u.M32.cr3], + register_names[u.M32.r2]); +} + +static void +ia64_print_M33(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.M33.r1], + control_names[u.M33.cr3]); +} + +static void +ia64_print_M34(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=ar.pfs,0,%d,%d,%d", + name, + register_names[u.M34.r1], + u.M34.sol, + u.M34.sof - u.M34.sol, + u.M34.sor << 3); +} + +static void +ia64_print_M35(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + if (u.M35.x6 == 0x2D) + db_printf("%s psr.l=%s", + name, + register_names[u.M35.r2]); + else + db_printf("%s psr.um=%s", + name, + register_names[u.M35.r2]); +} + +static void +ia64_print_M36(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + if (u.M35.x6 == 0x25) + db_printf("%s %s=psr", + name, + register_names[u.M36.r1]); + else + db_printf("%s %s=psr.um", + name, + register_names[u.M36.r1]); +} + +static void +ia64_print_M37(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s 0x%x", + name, + (u.M37.i << 20) | u.M37.imm20a); +} + +static void +ia64_print_M38(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%s", + name, + register_names[u.M38.r1], + register_names[u.M38.r3], + register_names[u.M38.r2]); +} + +static void +ia64_print_M39(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s,%d", + name, + register_names[u.M39.r1], + register_names[u.M39.r3], + u.M39.i2b); +} + +static void +ia64_print_M40(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s,%d", + name, + register_names[u.M40.r3], + u.M40.i2b); +} + +static void +ia64_print_M41(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s", + name, + register_names[u.M41.r2]); +} + +static void +ia64_print_M42(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + static const char *base[] = { + "rr", "dbr", "ibr", "pkr", "pmc", "pmd", "dtr", "itr" + }; + u.ins = ins; + db_printf("%s %s[%s]=%s", + name, + base[u.M42.x6], + register_names[u.M42.r3], + register_names[u.M42.r2]); +} + +static void +ia64_print_M43(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + static const char *base[] = { + "rr", "dbr", "ibr", "pkr", "pmc", "pmd", "dtr", "itr" + }; + u.ins = ins; + db_printf("%s %s=%s[%s]", + name, + register_names[u.M43.r1], + base[u.M43.x6 & 0x7], + register_names[u.M43.r3]); +} + +static void +ia64_print_M44(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s 0x%x", + name, + (u.M44.i << 23) | (u.M44.i2d << 21) | u.M44.imm21a); +} + +static void +ia64_print_M45(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.M45.r3], + register_names[u.M45.r2]); +} + +static void +ia64_print_M46(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %s=%s", + name, + register_names[u.M46.r1], + register_names[u.M46.r3]); +} + +static const char *ptable[] = { ".few", ".many" }; +static const char *whtable[] = { ".sptk", ".spnt", ".dptk", ".dpnt" }; +static const char *dtable[] = { "", ".clr" }; +static const char *ihtable[] = { "", ".imp" }; + +static void +ia64_print_B1(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s%s ", + name, + whtable[u.B1.wh], + ptable[u.B1.p], + dtable[u.B1.d]); + db_printsym((loc & ~15) + + (sign_extend((u.B1.s << 20) | u.B1.imm20b, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_B3(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s%s %s=", + name, + whtable[u.B3.wh], + ptable[u.B3.p], + dtable[u.B3.d], + branch_names[u.B3.b1]); + db_printsym((loc & ~15) + + (sign_extend((u.B3.s << 20) | u.B3.imm20b, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_B4(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s%s %s", + name, + whtable[u.B4.wh], + ptable[u.B4.p], + dtable[u.B4.d], + branch_names[u.B4.b2]); +} + +static void +ia64_print_B5(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s%s %s=%s", + name, + whtable[u.B5.wh], + ptable[u.B5.p], + dtable[u.B5.d], + branch_names[u.B5.b1], + branch_names[u.B5.b2]); +} + +static void +ia64_print_B6(const char *name, u_int64_t ins, db_addr_t loc) +{ + static const char *whtable[] = { ".sptk", ".loop", ".dptk", ".exit" }; + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s ", + name, + whtable[u.B6.wh], + ihtable[u.B6.ih]); + db_printsym((loc & ~15) + + (sign_extend((u.B6.s << 20) | u.B6.imm20b, 21) << 4), + DB_STGY_PROC); + db_printf("%x", (u.B6.t2e << 7) | u.B6.timm7a); +} + +static void +ia64_print_B7(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s%s %s,%x", + name, + whtable[u.B7.wh], + ihtable[u.B7.ih], + branch_names[u.B7.b2], + (u.B7.t2e << 7) | u.B7.timm7a); +} + +static void +ia64_print_B8(const char *name, u_int64_t ins, db_addr_t loc) +{ + db_printf("%s", name); +} + +static void +ia64_print_B9(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s %x", + name, + (u.B9.i << 20) | u.B9.imm20a); +} + +static const char *sftable[] = { ".s0", ".s1", ".s2", ".s3" }; + +static void +ia64_print_F1(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s f%d=f%d,f%d,f%d", + name, + sftable[u.F1.sf], + u.F1.f1, + u.F1.f3, + u.F1.f4, + u.F1.f2); +} + +static void +ia64_print_F2(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=f%d,f%d,f%d", + name, + u.F2.f1, + u.F2.f3, + u.F2.f4, + u.F2.f2); +} + +static void +ia64_print_F3(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=f%d,f%d,f%d", + name, + u.F3.f1, + u.F3.f3, + u.F3.f4, + u.F3.f2); +} + +static void +ia64_print_F4(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s p%d,p%d=f%d,f%d", + name, + sftable[u.F4.sf], + u.F4.p1, + u.F4.p2, + u.F4.f2, + u.F4.f3); +} + +static void +ia64_print_F5(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s p%d,p%d=f%d,0x%x", + name, + sftable[u.F4.sf], + u.F5.p1, + u.F5.p2, + u.F5.f2, + (u.F5.fclass7c << 2) | u.F5.fc2); +} + +static void +ia64_print_F6(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s f%d,p%d=f%d,f%d", + name, + sftable[u.F6.sf], + u.F6.f1, + u.F6.p2, + u.F6.f2, + u.F6.f3); +} + +static void +ia64_print_F7(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s f%d,p%d=f%d", + name, + sftable[u.F7.sf], + u.F7.f1, + u.F7.p2, + u.F7.f3); +} + +static void +ia64_print_F8(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s f%d=f%d,f%d", + name, + sftable[u.F8.sf], + u.F8.f1, + u.F8.f2, + u.F8.f3); +} + +static void +ia64_print_F9(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=f%d,f%d", + name, + u.F9.f1, + u.F9.f2, + u.F9.f3); +} + +static void +ia64_print_F10(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s f%d=f%d", + name, + sftable[u.F10.sf], + u.F10.f1, + u.F10.f2); +} + +static void +ia64_print_F11(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s f%d=f%d", + name, + u.F11.f1, + u.F11.f2); +} + +static void +ia64_print_F12(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s 0x%x,0x%x", + name, + sftable[u.F12.sf], + u.F12.amask7b, + u.F12.omask7c); +} + +static void +ia64_print_F13(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s", + name, + sftable[u.F13.sf]); +} + +static void +ia64_print_F14(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s%s ", + name, + sftable[u.F14.sf]); + db_printsym((loc & ~15) + (sign_extend((u.F14.s << 20) + | u.F14.imm20a, 21) << 4), + DB_STGY_PROC); +} + +static void +ia64_print_F15(const char *name, u_int64_t ins, db_addr_t loc) +{ + union ia64_instruction u; + u.ins = ins; + db_printf("%s 0x%x", + name, + (u.F15.i << 20) | u.F15.imm20a); +} + +static void +ia64_print_X1(const char *name, u_int64_t ins, db_addr_t loc) +{ + struct ia64_bundle b; + union ia64_instruction u; + u.ins = ins; + ia64_fetch_bundle(loc, &b); + db_printf("%s %lx", + name, + (b.slot[1] << 21) | (u.X1.i << 20) | u.X1.imm20a); +} + +static void +ia64_print_X2(const char *name, u_int64_t ins, db_addr_t loc) +{ + struct ia64_bundle b; + union ia64_instruction u; + u.ins = ins; + ia64_fetch_bundle(loc, &b); + db_printf("%s %s=%lx", + name, + register_names[u.X2.r1], + (((long)u.X2.i << 63) | (b.slot[1] << 22) | (u.X2.ic << 21) + | (u.X2.imm5c << 16) | (u.X2.imm9d << 7) | u.X2.imm7b)); +} + +struct ia64_opcode { + const char* name; + u_int64_t value; + u_int64_t mask; + void (*print)(const char*, u_int64_t, db_addr_t loc); +}; + +#define field(n,s,e) (((u_int64_t)(n) & ((1 << (e-s+1))-1)) << s) + +#define OP(n) field(n,37,40) +#define Za(n) field(n,36,36) +#define Tb(n) field(n,36,36) +#define S(n) field(n,36,36) +#define X2a(n) field(n,34,35) +#define X2(n) field(n,34,35) +#define Ve(n) field(n,33,33) +#define Zb(n) field(n,33,33) +#define Ta(n) field(n,33,33) +#define X4(n) field(n,29,32) +#define X2b(n) field(n,27,28) +#define I(n) field(n,13,19) +#define C(n) field(n,12,12) + +#define mOP OP(~0) +#define mZa Za(~0) +#define mTb Tb(~0) +#define mS S(~0) +#define mX2a X2a(~0) +#define mX2 X2(~0) +#define mVe Ve(~0) +#define mZb Zb(~0) +#define mTa Ta(~0) +#define mX4 X4(~0) +#define mX2b X2b(~0) +#define mI I(~0) +#define mC C(~0) + +#define OPX2aVe(a,b,c) \ + OP(a)|X2a(b)|Ve(c), mOP|mX2a|mVe +#define OPX2aVeSI(a,b,c,d,e) \ + OP(a)|X2a(b)|Ve(c)|S(d)|I(e), mOP|mX2a|mVe|mS|mI +#define OPX2aVeX4X2b(a,b,c,d,e) \ + OP(a)|X2a(b)|Ve(c)|X4(d)|X2b(e), mOP|mX2a|mVe|mX4|mX2b +#define OPX2aVeX4(a,b,c,d) \ + OP(a)|X2a(b)|Ve(c)|X4(d), mOP|mX2a|mVe|mX4 +#define OPX2TbTaC(a,b,c,d,e) \ + OP(a)|X2(b)|Tb(c)|Ta(d)|C(e), mOP|mX2|mTb|mTa|mC +#define OPX2TaC(a,b,c,d) \ + OP(a)|X2(b)|Ta(c)|C(d), mOP|mX2|mTa|mC +#define OPX2aZaZbX4X2b(a,b,c,d,e,f) \ + OP(a)|X2a(b)|Za(c)|Zb(d)|X4(e)|X2b(f), mOP|mX2a|mZa|mZb|mX4|mX2b +#define OPX2aZaZbX4(a,b,c,d,e) \ + OP(a)|X2a(b)|Za(c)|Zb(d)|X4(e), mOP|mX2a|mZa|mZb|mX4 +#define OPZaZbVeX2aX2bX2c(a,b,c,d,e,f,g) \ + OP(a)|Za(b)|Zb(c)|Ve(d)|X2a(e)|X2b(f)|X2c(g), \ + mOP|mZa|mZb|mVe|mX2a|mX2b|mX2c +#define OPZaZbVeX2aX2b(a,b,c,d,e,f) \ + OP(a)|Za(b)|Zb(c)|Ve(d)|X2a(e)|X2b(f), \ + mOP|mZa|mZb|mVe|mX2a|mX2b + +static struct ia64_opcode A_opcodes[] = { + + /* Table 4-8 */ + {"mov", OPX2aVeSI(8,2,0,0,0), ia64_print_A4_mov}, + {"adds", OPX2aVe(8,2,0), ia64_print_A4}, + {"addp4", OPX2aVe(8,3,0), ia64_print_A4}, + + /* Table 4-9 */ + {"add", OPX2aVeX4X2b(8,0,0,0,0), ia64_print_A1}, + {"add", OPX2aVeX4X2b(8,0,0,0,0), ia64_print_A1_comma1}, + {"sub", OPX2aVeX4X2b(8,0,0,1,0), ia64_print_A1_comma1}, + {"sub", OPX2aVeX4X2b(8,0,0,1,1), ia64_print_A1}, + {"addp4", OPX2aVeX4X2b(8,0,0,2,0), ia64_print_A1}, + {"and", OPX2aVeX4X2b(8,0,0,3,0), ia64_print_A1}, + {"andcm", OPX2aVeX4X2b(8,0,0,3,1), ia64_print_A1}, + {"or", OPX2aVeX4X2b(8,0,0,3,2), ia64_print_A1}, + {"xor", OPX2aVeX4X2b(8,0,0,3,3), ia64_print_A1}, + {"shladd", OPX2aVeX4(8,0,0,4), ia64_print_A2}, + {"shladdp4", OPX2aVeX4(8,0,0,6), ia64_print_A2}, + {"sub", OPX2aVeX4X2b(8,0,0,9,1), ia64_print_A3}, + {"and", OPX2aVeX4X2b(8,0,0,11,0), ia64_print_A3}, + {"andcm", OPX2aVeX4X2b(8,0,0,11,1), ia64_print_A3}, + {"or", OPX2aVeX4X2b(8,0,0,11,2), ia64_print_A3}, + {"xor", OPX2aVeX4X2b(8,0,0,11,3), ia64_print_A3}, + + /* Section 4.2.1.5 */ + {"addl", OP(9),mOP, ia64_print_A5}, + + /* Table 4-10 */ + {"cmp.lt", OPX2TbTaC(12,0,0,0,0), ia64_print_A6}, + {"cmp.lt.unc", OPX2TbTaC(12,0,0,0,1), ia64_print_A6}, + {"cmp.eq.and", OPX2TbTaC(12,0,0,1,0), ia64_print_A6}, + {"cmp.ne.and", OPX2TbTaC(12,0,0,1,1), ia64_print_A6}, + {"cmp.gt.and", OPX2TbTaC(12,0,1,0,0), ia64_print_A7}, + {"cmp.le.and", OPX2TbTaC(12,0,1,0,1), ia64_print_A7}, + {"cmp.ge.and", OPX2TbTaC(12,0,1,1,0), ia64_print_A7}, + {"cmp.lt.and", OPX2TbTaC(12,0,1,1,1), ia64_print_A7}, + {"cmp4.lt", OPX2TbTaC(12,1,0,0,0), ia64_print_A6}, + {"cmp4.lt.unc", OPX2TbTaC(12,1,0,0,1), ia64_print_A6}, + {"cmp4.eq.and", OPX2TbTaC(12,1,0,1,0), ia64_print_A6}, + {"cmp4.ne.and", OPX2TbTaC(12,1,0,1,1), ia64_print_A6}, + {"cmp4.gt.and", OPX2TbTaC(12,1,1,0,0), ia64_print_A7}, + {"cmp4.le.and", OPX2TbTaC(12,1,1,0,1), ia64_print_A7}, + {"cmp4.ge.and", OPX2TbTaC(12,1,1,1,0), ia64_print_A7}, + {"cmp4.lt.and", OPX2TbTaC(12,1,1,1,1), ia64_print_A7}, + {"cmp.ltu", OPX2TbTaC(13,0,0,0,0), ia64_print_A6}, + {"cmp.ltu.unc", OPX2TbTaC(13,0,0,0,1), ia64_print_A6}, + {"cmp.eq.or", OPX2TbTaC(13,0,0,1,0), ia64_print_A6}, + {"cmp.ne.or", OPX2TbTaC(13,0,0,1,1), ia64_print_A6}, + {"cmp.gt.or", OPX2TbTaC(13,0,1,0,0), ia64_print_A7}, + {"cmp.le.or", OPX2TbTaC(13,0,1,0,1), ia64_print_A7}, + {"cmp.ge.or", OPX2TbTaC(13,0,1,1,0), ia64_print_A7}, + {"cmp.lt.or", OPX2TbTaC(13,0,1,1,1), ia64_print_A7}, + {"cmp4.ltu", OPX2TbTaC(13,1,0,0,0), ia64_print_A6}, + {"cmp4.ltu.unc", OPX2TbTaC(13,1,0,0,1), ia64_print_A6}, + {"cmp4.eq.or", OPX2TbTaC(13,1,0,1,0), ia64_print_A6}, + {"cmp4.ne.or", OPX2TbTaC(13,1,0,1,1), ia64_print_A6}, + {"cmp4.gt.or", OPX2TbTaC(13,1,1,0,0), ia64_print_A7}, + {"cmp4.le.or", OPX2TbTaC(13,1,1,0,1), ia64_print_A7}, + {"cmp4.ge.or", OPX2TbTaC(13,1,1,1,0), ia64_print_A7}, + {"cmp4.lt.or", OPX2TbTaC(13,1,1,1,1), ia64_print_A7}, + {"cmp.eq", OPX2TbTaC(14,0,0,0,0), ia64_print_A6}, + {"cmp.eq.unc", OPX2TbTaC(14,0,0,0,1), ia64_print_A6}, + {"cmp.eq.andcm", OPX2TbTaC(14,0,0,1,0), ia64_print_A6}, + {"cmp.ne.andcm", OPX2TbTaC(14,0,0,1,1), ia64_print_A6}, + {"cmp.gt.andcm", OPX2TbTaC(14,0,1,0,0), ia64_print_A7}, + {"cmp.le.andcm", OPX2TbTaC(14,0,1,0,1), ia64_print_A7}, + {"cmp.ge.andcm", OPX2TbTaC(14,0,1,1,0), ia64_print_A7}, + {"cmp.lt.andcm", OPX2TbTaC(14,0,1,1,1), ia64_print_A7}, + {"cmp4.eq", OPX2TbTaC(14,1,0,0,0), ia64_print_A6}, + {"cmp4.eq.unc", OPX2TbTaC(14,1,0,0,1), ia64_print_A6}, + {"cmp4.eq.andcm", OPX2TbTaC(14,1,0,1,0), ia64_print_A6}, + {"cmp4.ne.andcm", OPX2TbTaC(14,1,0,1,1), ia64_print_A6}, + {"cmp4.gt.andcm", OPX2TbTaC(14,1,1,0,0), ia64_print_A7}, + {"cmp4.le.andcm", OPX2TbTaC(14,1,1,0,1), ia64_print_A7}, + {"cmp4.ge.andcm", OPX2TbTaC(14,1,1,1,0), ia64_print_A7}, + {"cmp4.lt.andcm", OPX2TbTaC(14,1,1,1,1), ia64_print_A7}, + + /* Table 4-11 */ + {"cmp.lt", OPX2TaC(12,2,0,0), ia64_print_A8}, + {"cmp.lt.unc", OPX2TaC(12,2,0,1), ia64_print_A8}, + {"cmp.eq.and", OPX2TaC(12,2,1,0), ia64_print_A8}, + {"cmp.ne.and", OPX2TaC(12,2,1,1), ia64_print_A8}, + {"cmp4.lt", OPX2TaC(12,3,0,0), ia64_print_A8}, + {"cmp4.lt.unc", OPX2TaC(12,3,0,1), ia64_print_A8}, + {"cmp4.eq.and", OPX2TaC(12,3,1,0), ia64_print_A8}, + {"cmp4.ne.and", OPX2TaC(12,3,1,1), ia64_print_A8}, + {"cmp.ltu", OPX2TaC(13,2,0,0), ia64_print_A8}, + {"cmp.ltu.unc", OPX2TaC(13,2,0,1), ia64_print_A8}, + {"cmp.eq.or", OPX2TaC(13,2,1,0), ia64_print_A8}, + {"cmp.ne.or", OPX2TaC(13,2,1,1), ia64_print_A8}, + {"cmp4.ltu", OPX2TaC(13,3,0,0), ia64_print_A8}, + {"cmp4.ltu.unc", OPX2TaC(13,3,0,1), ia64_print_A8}, + {"cmp4.eq.or", OPX2TaC(13,3,1,0), ia64_print_A8}, + {"cmp4.ne.or", OPX2TaC(13,3,1,1), ia64_print_A8}, + {"cmp.eq", OPX2TaC(14,2,0,0), ia64_print_A8}, + {"cmp.eq.unc", OPX2TaC(14,2,0,1), ia64_print_A8}, + {"cmp.eq.or.andcm", OPX2TaC(14,2,1,0), ia64_print_A8}, + {"cmp.ne.or.andcm", OPX2TaC(14,2,1,1), ia64_print_A8}, + {"cmp4.eq", OPX2TaC(14,3,0,0), ia64_print_A8}, + {"cmp4.eq.unc", OPX2TaC(14,3,0,1), ia64_print_A8}, + {"cmp4.eq.or.andcm", OPX2TaC(14,3,1,0), ia64_print_A8}, + {"cmp4.ne.or.andcm", OPX2TaC(14,3,1,1), ia64_print_A8}, + + /* Table 4-13 */ + {"padd1", OPX2aZaZbX4X2b(8,1,0,0,0,0), ia64_print_A9}, + {"padd1.sss", OPX2aZaZbX4X2b(8,1,0,0,0,1), ia64_print_A9}, + {"padd1.uuu", OPX2aZaZbX4X2b(8,1,0,0,0,2), ia64_print_A9}, + {"padd1.uus", OPX2aZaZbX4X2b(8,1,0,0,0,3), ia64_print_A9}, + {"psub1", OPX2aZaZbX4X2b(8,1,0,0,1,0), ia64_print_A9}, + {"psub1.sss", OPX2aZaZbX4X2b(8,1,0,0,1,1), ia64_print_A9}, + {"psub1.uuu", OPX2aZaZbX4X2b(8,1,0,0,1,2), ia64_print_A9}, + {"psub1.uus", OPX2aZaZbX4X2b(8,1,0,0,1,3), ia64_print_A9}, + {"pavg1", OPX2aZaZbX4X2b(8,1,0,0,2,2), ia64_print_A9}, + {"pavg1.raz", OPX2aZaZbX4X2b(8,1,0,0,2,3), ia64_print_A9}, + {"pavgsub1", OPX2aZaZbX4X2b(8,1,0,0,3,2), ia64_print_A9}, + {"pcmp1.eq", OPX2aZaZbX4X2b(8,1,0,0,9,0), ia64_print_A9}, + {"pcmp1.gt", OPX2aZaZbX4X2b(8,1,0,0,9,1), ia64_print_A9}, + + /* Table 4-14 */ + {"padd2", OPX2aZaZbX4X2b(8,1,0,1,0,0), ia64_print_A9}, + {"padd2.sss", OPX2aZaZbX4X2b(8,1,0,1,0,1), ia64_print_A9}, + {"padd2.uuu", OPX2aZaZbX4X2b(8,1,0,1,0,2), ia64_print_A9}, + {"padd2.uus", OPX2aZaZbX4X2b(8,1,0,1,0,3), ia64_print_A9}, + {"psub2", OPX2aZaZbX4X2b(8,1,0,1,1,0), ia64_print_A9}, + {"psub2.sss", OPX2aZaZbX4X2b(8,1,0,1,1,1), ia64_print_A9}, + {"psub2.uuu", OPX2aZaZbX4X2b(8,1,0,1,1,2), ia64_print_A9}, + {"psub2.uus", OPX2aZaZbX4X2b(8,1,0,1,1,3), ia64_print_A9}, + {"pavg2", OPX2aZaZbX4X2b(8,1,0,1,2,2), ia64_print_A9}, + {"pavg2.raz", OPX2aZaZbX4X2b(8,1,0,1,2,3), ia64_print_A9}, + {"pavgsub2", OPX2aZaZbX4X2b(8,1,0,1,3,2), ia64_print_A9}, + {"pshladd2", OPX2aZaZbX4(8,1,0,1,4), ia64_print_A10}, + {"pshradd2", OPX2aZaZbX4(8,1,0,1,6), ia64_print_A10}, + {"pcmp2.eq", OPX2aZaZbX4X2b(8,1,0,1,9,0), ia64_print_A9}, + {"pcmp2.gt", OPX2aZaZbX4X2b(8,1,0,1,9,1), ia64_print_A9}, + + /* Table 4-15 */ + {"padd4", OPX2aZaZbX4X2b(8,1,1,0,0,0), ia64_print_A9}, + {"psub4", OPX2aZaZbX4X2b(8,1,1,0,1,0), ia64_print_A9}, + {"pcmp4.eq", OPX2aZaZbX4X2b(8,1,1,0,9,0), ia64_print_A9}, + {"pcmp4.gt", OPX2aZaZbX4X2b(8,1,1,0,9,1), ia64_print_A9}, + + {"illegal.a", 0,0, ia64_print_ill}, + {0}, +}; + +#undef OP +#undef Za +#undef Tb +#undef S +#undef X2a +#undef X2 +#undef Ve +#undef Zb +#undef Ta +#undef X4 +#undef X2b +#undef C + +#undef mOP +#undef mZa +#undef mTb +#undef mS +#undef mX2a +#undef mX2 +#undef mVe +#undef mZb +#undef mTa +#undef mX4 +#undef mX2b +#undef mC + +#undef OPX2aVe +#undef OPX2aVeSI +#undef OPX2aVeX4X2b +#undef OPX2aVeX4 +#undef OPX2TbTaC +#undef OPX2TaC +#undef OPX2aZaZbX4X2b +#undef OPX2aZaZbX4 +#undef OPZaZbVeX2aX2bX2c +#undef OPZaZbVeX2aX2b + +#define OP(n) field(n,37,40) +#define Za(n) field(n,36,36) +#define Tb(n) field(n,36,36) +#define X2a(n) field(n,34,35) +#define X2(n) field(n,34,35) +#define X3(n) field(n,33,35) +#define X6(n) field(n,27,32) +#define Zb(n) field(n,33,33) +#define X(n) field(n,33,33) +#define Ta(n) field(n,33,33) +#define Ve(n) field(n,32,32) +#define X2c(n) field(n,30,31) +#define X2b(n) field(n,28,29) +#define YY(n) field(n,26,26) +#define Y(n) field(n,13,13) +#define C(n) field(n,12,12) + +#define mOP OP(~0) +#define mZa Za(~0) +#define mTb Tb(~0) +#define mX2a X2a(~0) +#define mX2 X2(~0) +#define mX3 X3(~0) +#define mX6 X6(~0) +#define mZb Zb(~0) +#define mX X(~0) +#define mTa Ta(~0) +#define mVe Ve(~0) +#define mX2c X2c(~0) +#define mX2b X2b(~0) +#define mYY YY(~0) +#define mY Y(~0) +#define mC C(~0) + +#define OPZaZbVeX2aX2bX2c(a,b,c,d,e,f,g) \ + OP(a)|Za(b)|Zb(c)|Ve(d)|X2a(e)|X2b(f)|X2c(g), \ + mOP|mZa|mZb|mVe|mX2a|mX2b|mX2c +#define OPZaZbVeX2aX2b(a,b,c,d,e,f) \ + OP(a)|Za(b)|Zb(c)|Ve(d)|X2a(e)|X2b(f), \ + mOP|mZa|mZb|mVe|mX2a|mX2b +#define OPX2XY(a,b,c,d) \ + OP(a)|X2(b)|X(c)|Y(d), mOP|mX2|mX|mY +#define OPX2XYY(a,b,c,d) \ + OP(a)|X2(b)|X(c)|YY(d), mOP|mX2|mX|mYY +#define OPX2X(a,b,c) \ + OP(a)|X2(b)|X(c), mOP|mX2|mX +#define OPX2TaTbCY(a,b,c,d,e,f) \ + OP(a)|X2(b)|Ta(c)|Tb(d)|C(e)|Y(f), mOP|mX2|mTa|mTb|mC|mY +#define OPX3(a,b) \ + OP(a)|X3(b), mOP|mX3 +#define OPX3X6(a,b,c) \ + OP(a)|X3(b)|X6(c), mOP|mX3|mX6 + +static struct ia64_opcode I_opcodes[] = { + /* Table 4-17 */ + {"unpack1.h", OPZaZbVeX2aX2bX2c(7,0,0,0,2,0,1), ia64_print_I2}, + {"mix1.r", OPZaZbVeX2aX2bX2c(7,0,0,0,2,0,2), ia64_print_I2}, + {"pmin1.u", OPZaZbVeX2aX2bX2c(7,0,0,0,2,1,0), ia64_print_I2}, + {"pmax2.u", OPZaZbVeX2aX2bX2c(7,0,0,0,2,1,1), ia64_print_I2}, + {"unpack1.l", OPZaZbVeX2aX2bX2c(7,0,0,0,2,2,1), ia64_print_I2}, + {"mix1.l", OPZaZbVeX2aX2bX2c(7,0,0,0,2,2,2), ia64_print_I2}, + {"psad1", OPZaZbVeX2aX2bX2c(7,0,0,0,2,3,2), ia64_print_I2}, + {"mux1", OPZaZbVeX2aX2bX2c(7,0,0,0,3,2,2), ia64_print_I3}, + + /* Table 4-18 */ + {"pshr2.u", OPZaZbVeX2aX2bX2c(7,0,1,0,0,0,0), ia64_print_I5}, + {"pshl2", OPZaZbVeX2aX2bX2c(7,0,1,0,0,0,1), ia64_print_I7}, + {"pmpyshr2.u", OPZaZbVeX2aX2b(7,0,1,0,0,1), ia64_print_I1}, + {"pshr2", OPZaZbVeX2aX2bX2c(7,0,1,0,0,2,0), ia64_print_I5}, + {"pmpyshr2", OPZaZbVeX2aX2b(7,0,1,0,0,3), ia64_print_I1}, + {"pshr2.u", OPZaZbVeX2aX2bX2c(7,0,1,0,1,1,0), ia64_print_I6}, + {"popcnt", OPZaZbVeX2aX2bX2c(7,0,1,0,1,1,2), ia64_print_I9}, + {"pshr2", OPZaZbVeX2aX2bX2c(7,0,1,0,1,3,0), ia64_print_I6}, + {"pack2.uss", OPZaZbVeX2aX2bX2c(7,0,1,0,2,0,0), ia64_print_I2}, + {"unpack2.h", OPZaZbVeX2aX2bX2c(7,0,1,0,2,0,1), ia64_print_I2}, + {"mix2.r", OPZaZbVeX2aX2bX2c(7,0,1,0,2,0,2), ia64_print_I2}, + {"pmpy2.r", OPZaZbVeX2aX2bX2c(7,0,1,0,2,1,3), ia64_print_I2}, + {"pack2.sss", OPZaZbVeX2aX2bX2c(7,0,1,0,2,2,0), ia64_print_I2}, + {"unpack2.l", OPZaZbVeX2aX2bX2c(7,0,1,0,2,2,1), ia64_print_I2}, + {"mix2.l", OPZaZbVeX2aX2bX2c(7,0,1,0,2,2,2), ia64_print_I2}, + {"pmin2", OPZaZbVeX2aX2bX2c(7,0,1,0,2,3,0), ia64_print_I2}, + {"pmax2", OPZaZbVeX2aX2bX2c(7,0,1,0,2,3,1), ia64_print_I2}, + {"pmpy2.l", OPZaZbVeX2aX2bX2c(7,0,1,0,2,3,3), ia64_print_I2}, + {"pshl2", OPZaZbVeX2aX2bX2c(7,0,1,0,3,1,1), ia64_print_I8}, + {"mux2", OPZaZbVeX2aX2bX2c(7,0,1,0,3,2,2), ia64_print_I4}, + + /* Table 4-19 */ + {"pshr4.u", OPZaZbVeX2aX2bX2c(7,1,0,0,0,0,0), ia64_print_I5}, + {"pshl4", OPZaZbVeX2aX2bX2c(7,1,0,0,0,0,1), ia64_print_I7}, + {"pshr4", OPZaZbVeX2aX2bX2c(7,1,0,0,0,2,0), ia64_print_I5}, + {"pshr4.u", OPZaZbVeX2aX2bX2c(7,1,0,0,1,1,0), ia64_print_I6}, + {"pshr4", OPZaZbVeX2aX2bX2c(7,1,0,0,1,3,0), ia64_print_I6}, + {"unpack4.h", OPZaZbVeX2aX2bX2c(7,1,0,0,2,0,1), ia64_print_I2}, + {"mix4.r", OPZaZbVeX2aX2bX2c(7,1,0,0,2,0,2), ia64_print_I2}, + {"pack4.sss", OPZaZbVeX2aX2bX2c(7,1,0,0,2,2,0), ia64_print_I2}, + {"unpack4.l", OPZaZbVeX2aX2bX2c(7,1,0,0,2,2,1), ia64_print_I2}, + {"mix4.l", OPZaZbVeX2aX2bX2c(7,1,0,0,2,2,2), ia64_print_I2}, + {"pshl4", OPZaZbVeX2aX2bX2c(7,1,0,0,3,1,1), ia64_print_I8}, + + /* Table 4-20 */ + {"shr.u", OPZaZbVeX2aX2bX2c(7,1,1,0,0,0,0), ia64_print_I5}, + {"shl", OPZaZbVeX2aX2bX2c(7,1,1,0,0,0,1), ia64_print_I7}, + {"shr", OPZaZbVeX2aX2bX2c(7,1,1,0,0,2,0), ia64_print_I5}, + + /* Table 4-21 */ + {"extr.u", OPX2XY(5,1,0,0), ia64_print_I11}, + {"extr", OPX2XY(5,1,0,1), ia64_print_I11}, + {"shrp", OPX2X(5,3,0), ia64_print_I10}, + + /* Table 4-22 */ + {"dep.z", OPX2XYY(5,1,1,0), ia64_print_I12}, + {"dep.z", OPX2XYY(5,1,1,1), ia64_print_I13}, + {"dep", OPX2X(5,3,1), ia64_print_I14}, + + /* Table 4-23 */ + {"tbit.z", OPX2TaTbCY(5,0,0,0,0,0), ia64_print_I16}, + {"tnat.z", OPX2TaTbCY(5,0,0,0,0,1), ia64_print_I17}, + {"tbit.z.unc", OPX2TaTbCY(5,0,0,0,1,0), ia64_print_I16}, + {"tnat.z.unc", OPX2TaTbCY(5,0,0,0,1,1), ia64_print_I17}, + {"tbit.z.and", OPX2TaTbCY(5,0,0,1,0,0), ia64_print_I16}, + {"tnat.z.and", OPX2TaTbCY(5,0,0,1,0,1), ia64_print_I17}, + {"tbit.nz.and", OPX2TaTbCY(5,0,0,1,1,0), ia64_print_I16}, + {"tnat.nz.and", OPX2TaTbCY(5,0,0,1,1,1), ia64_print_I17}, + {"tbit.z.or", OPX2TaTbCY(5,0,1,0,0,0), ia64_print_I16}, + {"tnat.z.or", OPX2TaTbCY(5,0,1,0,0,1), ia64_print_I17}, + {"tbit.nz.or", OPX2TaTbCY(5,0,1,0,1,0), ia64_print_I16}, + {"tnat.nz.or", OPX2TaTbCY(5,0,1,0,1,1), ia64_print_I17}, + {"tbit.z.or.andcm", OPX2TaTbCY(5,0,1,1,0,0), ia64_print_I16}, + {"tnat.z.or.andcm", OPX2TaTbCY(5,0,1,1,0,1), ia64_print_I17}, + {"tbit.nz.or.andcm", OPX2TaTbCY(5,0,1,1,1,0), ia64_print_I16}, + {"tnat.nz.or.andcm", OPX2TaTbCY(5,0,1,1,1,1), ia64_print_I17}, + + /* Section 4.3.2.6 */ + {"dep", OP(4),mOP, ia64_print_I15}, + + /* Table 4-24 */ + {"chk.s.i", OPX3(0,1), ia64_print_I20}, + {"mov", OPX3(0,2), ia64_print_I24}, + {"mov", OPX3(0,3), ia64_print_I23}, + {"mov", OPX3(0,7), ia64_print_I21}, + + /* Table 4-25 */ + {"break.i", OPX3X6(0,0,0), ia64_print_I19}, + {"nop.i", OPX3X6(0,0,1), ia64_print_I19}, + {"mov.i", OPX3X6(0,0,10), ia64_print_I27}, + {"zxt1", OPX3X6(0,0,16), ia64_print_I29}, + {"zxt2", OPX3X6(0,0,17), ia64_print_I29}, + {"zxt4", OPX3X6(0,0,18), ia64_print_I29}, + {"sxt1", OPX3X6(0,0,20), ia64_print_I29}, + {"sxt2", OPX3X6(0,0,21), ia64_print_I29}, + {"sxt4", OPX3X6(0,0,22), ia64_print_I29}, + {"czx1.l", OPX3X6(0,0,24), ia64_print_I29}, + {"czx2.l", OPX3X6(0,0,25), ia64_print_I29}, + {"czx1.r", OPX3X6(0,0,28), ia64_print_I29}, + {"czx2.r", OPX3X6(0,0,29), ia64_print_I29}, + {"mov.i", OPX3X6(0,0,42), ia64_print_I26}, + {"mov", OPX3X6(0,0,48), ia64_print_I25}, + {"mov", OPX3X6(0,0,49), ia64_print_I22}, + {"mov.i", OPX3X6(0,0,50), ia64_print_I28}, + {"mov", OPX3X6(0,0,51), ia64_print_I25}, + + {"illegal.i", 0,0, ia64_print_ill}, + {0}, +}; + +#undef OP +#undef Za +#undef Tb +#undef X2a +#undef X2 +#undef X3 +#undef X6 +#undef Zb +#undef X +#undef Ta +#undef Ve +#undef X2c +#undef X2b +#undef YY +#undef Y +#undef C + +#undef mOP +#undef mZa +#undef mTb +#undef mX2a +#undef mX2 +#undef mX3 +#undef mX6 +#undef mZb +#undef mX +#undef mTa +#undef mVe +#undef mX2c +#undef mX2b +#undef mYY +#undef mY +#undef mC + +#undef OPZaZbVeX2aX2bX2c +#undef OPZaZbVeX2aX2b +#undef OPX2XY +#undef OPX2XYY +#undef OPX2X +#undef OPX2TaTbCY +#undef OPX3 +#undef OPX3X6 + +#define OP(n) field(n,37,40) +#define M(n) field(n,36,36) +#define X3(n) field(n,33,35) +#define X6(n) field(n,30,35) +#define X2(n) field(n,31,32) +#define X4(n) field(n,27,30) +#define X6a(n) field(n,27,32) +#define X(n) field(n,27,27) + +#define mOP OP(~0) +#define mM M(~0) +#define mX3 X3(~0) +#define mX6 X6(~0) +#define mX2 X2(~0) +#define mX4 X4(~0) +#define mX6a X6a(~0) +#define mX X(~0) + +#define OPMXX6(a,b,c,d) \ + OP(a)|M(b)|X(c)|X6(d), mOP|mM|mX|mX6 +#define OPX6(a,b) \ + OP(a)|X6(b), mOP|mX6 +#define OPX3(a,b) \ + OP(a)|X3(b), mOP|mX3 +#define OPX3(a,b) \ + OP(a)|X3(b), mOP|mX3 +#define OPX3X4(a,b,c) \ + OP(a)|X3(b)|X4(c), mOP|mX3|mX4 +#define OPX3X4X2(a,b,c,d) \ + OP(a)|X3(b)|X4(c)|X2(d), mOP|mX3|mX4|mX2 +#define OPX3X6(a,b,c) \ + OP(a)|X3(b)|X6a(c), mOP|mX3|mX6a + +static struct ia64_opcode M_opcodes[] = { + + /* Table 4-29 */ + {"ld1", OPMXX6(4,0,0,0x00), ia64_print_M1}, + {"ld2", OPMXX6(4,0,0,0x01), ia64_print_M1}, + {"ld4", OPMXX6(4,0,0,0x02), ia64_print_M1}, + {"ld8", OPMXX6(4,0,0,0x03), ia64_print_M1}, + {"ld1.s", OPMXX6(4,0,0,0x04), ia64_print_M1}, + {"ld2.s", OPMXX6(4,0,0,0x05), ia64_print_M1}, + {"ld4.s", OPMXX6(4,0,0,0x06), ia64_print_M1}, + {"ld8.s", OPMXX6(4,0,0,0x07), ia64_print_M1}, + {"ld1.a", OPMXX6(4,0,0,0x08), ia64_print_M1}, + {"ld2.a", OPMXX6(4,0,0,0x09), ia64_print_M1}, + {"ld4.a", OPMXX6(4,0,0,0x0a), ia64_print_M1}, + {"ld8.a", OPMXX6(4,0,0,0x0b), ia64_print_M1}, + {"ld1.sa", OPMXX6(4,0,0,0x0c), ia64_print_M1}, + {"ld2.sa", OPMXX6(4,0,0,0x0d), ia64_print_M1}, + {"ld4.sa", OPMXX6(4,0,0,0x0e), ia64_print_M1}, + {"ld8.sa", OPMXX6(4,0,0,0x0f), ia64_print_M1}, + {"ld1.bias", OPMXX6(4,0,0,0x10), ia64_print_M1}, + {"ld2.bias", OPMXX6(4,0,0,0x11), ia64_print_M1}, + {"ld4.bias", OPMXX6(4,0,0,0x12), ia64_print_M1}, + {"ld8.bias", OPMXX6(4,0,0,0x13), ia64_print_M1}, + {"ld1.acq", OPMXX6(4,0,0,0x14), ia64_print_M1}, + {"ld2.acq", OPMXX6(4,0,0,0x15), ia64_print_M1}, + {"ld4.acq", OPMXX6(4,0,0,0x16), ia64_print_M1}, + {"ld8.acq", OPMXX6(4,0,0,0x17), ia64_print_M1}, + {"ld8.fill", OPMXX6(4,0,0,0x1b), ia64_print_M1}, + {"ld1.c.clr", OPMXX6(4,0,0,0x20), ia64_print_M1}, + {"ld2.c.clr", OPMXX6(4,0,0,0x21), ia64_print_M1}, + {"ld4.c.clr", OPMXX6(4,0,0,0x22), ia64_print_M1}, + {"ld8.c.clr", OPMXX6(4,0,0,0x23), ia64_print_M1}, + {"ld1.c.nc", OPMXX6(4,0,0,0x24), ia64_print_M1}, + {"ld2.c.nc", OPMXX6(4,0,0,0x25), ia64_print_M1}, + {"ld4.c.nc", OPMXX6(4,0,0,0x26), ia64_print_M1}, + {"ld8.c.nc", OPMXX6(4,0,0,0x27), ia64_print_M1}, + {"ld1.c.clr.acq", OPMXX6(4,0,0,0x28), ia64_print_M1}, + {"ld2.c.clr.acq", OPMXX6(4,0,0,0x29), ia64_print_M1}, + {"ld4.c.clr.acq", OPMXX6(4,0,0,0x2a), ia64_print_M1}, + {"ld8.c.clr.acq", OPMXX6(4,0,0,0x2b), ia64_print_M1}, + {"st1", OPMXX6(4,0,0,0x30), ia64_print_M4}, + {"st2", OPMXX6(4,0,0,0x31), ia64_print_M4}, + {"st4", OPMXX6(4,0,0,0x32), ia64_print_M4}, + {"st8", OPMXX6(4,0,0,0x33), ia64_print_M4}, + {"st1.rel", OPMXX6(4,0,0,0x34), ia64_print_M4}, + {"st2.rel", OPMXX6(4,0,0,0x35), ia64_print_M4}, + {"st4.rel", OPMXX6(4,0,0,0x36), ia64_print_M4}, + {"st8.rel", OPMXX6(4,0,0,0x37), ia64_print_M4}, + {"st8.spill", OPMXX6(4,0,0,0x3b), ia64_print_M4}, + + /* Table 4-30 */ + {"ld1", OPMXX6(4,1,0,0x00), ia64_print_M2}, + {"ld2", OPMXX6(4,1,0,0x01), ia64_print_M2}, + {"ld4", OPMXX6(4,1,0,0x02), ia64_print_M2}, + {"ld8", OPMXX6(4,1,0,0x03), ia64_print_M2}, + {"ld1.s", OPMXX6(4,1,0,0x04), ia64_print_M2}, + {"ld2.s", OPMXX6(4,1,0,0x05), ia64_print_M2}, + {"ld4.s", OPMXX6(4,1,0,0x06), ia64_print_M2}, + {"ld8.s", OPMXX6(4,1,0,0x07), ia64_print_M2}, + {"ld1.a", OPMXX6(4,1,0,0x08), ia64_print_M2}, + {"ld2.a", OPMXX6(4,1,0,0x09), ia64_print_M2}, + {"ld4.a", OPMXX6(4,1,0,0x0a), ia64_print_M2}, + {"ld8.a", OPMXX6(4,1,0,0x0b), ia64_print_M2}, + {"ld1.sa", OPMXX6(4,1,0,0x0c), ia64_print_M2}, + {"ld2.sa", OPMXX6(4,1,0,0x0d), ia64_print_M2}, + {"ld4.sa", OPMXX6(4,1,0,0x0e), ia64_print_M2}, + {"ld8.sa", OPMXX6(4,1,0,0x0f), ia64_print_M2}, + {"ld1.bias", OPMXX6(4,1,0,0x10), ia64_print_M2}, + {"ld2.bias", OPMXX6(4,1,0,0x11), ia64_print_M2}, + {"ld4.bias", OPMXX6(4,1,0,0x12), ia64_print_M2}, + {"ld8.bias", OPMXX6(4,1,0,0x13), ia64_print_M2}, + {"ld1.acq", OPMXX6(4,1,0,0x14), ia64_print_M2}, + {"ld2.acq", OPMXX6(4,1,0,0x15), ia64_print_M2}, + {"ld4.acq", OPMXX6(4,1,0,0x16), ia64_print_M2}, + {"ld8.acq", OPMXX6(4,1,0,0x17), ia64_print_M2}, + {"ld8.fill", OPMXX6(4,1,0,0x1b), ia64_print_M2}, + {"ld1.c.clr", OPMXX6(4,1,0,0x20), ia64_print_M2}, + {"ld2.c.clr", OPMXX6(4,1,0,0x21), ia64_print_M2}, + {"ld4.c.clr", OPMXX6(4,1,0,0x22), ia64_print_M2}, + {"ld8.c.clr", OPMXX6(4,1,0,0x23), ia64_print_M2}, + {"ld1.c.nc", OPMXX6(4,1,0,0x24), ia64_print_M2}, + {"ld2.c.nc", OPMXX6(4,1,0,0x25), ia64_print_M2}, + {"ld4.c.nc", OPMXX6(4,1,0,0x26), ia64_print_M2}, + {"ld8.c.nc", OPMXX6(4,1,0,0x27), ia64_print_M2}, + {"ld1.c.clr.acq", OPMXX6(4,1,0,0x28), ia64_print_M2}, + {"ld2.c.clr.acq", OPMXX6(4,1,0,0x29), ia64_print_M2}, + {"ld4.c.clr.acq", OPMXX6(4,1,0,0x2a), ia64_print_M2}, + {"ld8.c.clr.acq", OPMXX6(4,1,0,0x2b), ia64_print_M2}, + + /* Table 4-31 */ + {"ld1", OPX6(5,0x00), ia64_print_M3}, + {"ld2", OPX6(5,0x01), ia64_print_M3}, + {"ld4", OPX6(5,0x02), ia64_print_M3}, + {"ld8", OPX6(5,0x03), ia64_print_M3}, + {"ld1.s", OPX6(5,0x04), ia64_print_M3}, + {"ld2.s", OPX6(5,0x05), ia64_print_M3}, + {"ld4.s", OPX6(5,0x06), ia64_print_M3}, + {"ld8.s", OPX6(5,0x07), ia64_print_M3}, + {"ld1.a", OPX6(5,0x08), ia64_print_M3}, + {"ld2.a", OPX6(5,0x09), ia64_print_M3}, + {"ld4.a", OPX6(5,0x0a), ia64_print_M3}, + {"ld8.a", OPX6(5,0x0b), ia64_print_M3}, + {"ld1.sa", OPX6(5,0x0c), ia64_print_M3}, + {"ld2.sa", OPX6(5,0x0d), ia64_print_M3}, + {"ld4.sa", OPX6(5,0x0e), ia64_print_M3}, + {"ld8.sa", OPX6(5,0x0f), ia64_print_M3}, + {"ld1.bias", OPX6(5,0x10), ia64_print_M3}, + {"ld2.bias", OPX6(5,0x11), ia64_print_M3}, + {"ld4.bias", OPX6(5,0x12), ia64_print_M3}, + {"ld8.bias", OPX6(5,0x13), ia64_print_M3}, + {"ld1.acq", OPX6(5,0x14), ia64_print_M3}, + {"ld2.acq", OPX6(5,0x15), ia64_print_M3}, + {"ld4.acq", OPX6(5,0x16), ia64_print_M3}, + {"ld8.acq", OPX6(5,0x17), ia64_print_M3}, + {"ld8.fill", OPX6(5,0x1b), ia64_print_M3}, + {"ld1.c.clr", OPX6(5,0x20), ia64_print_M3}, + {"ld2.c.clr", OPX6(5,0x21), ia64_print_M3}, + {"ld4.c.clr", OPX6(5,0x22), ia64_print_M3}, + {"ld8.c.clr", OPX6(5,0x23), ia64_print_M3}, + {"ld1.c.nc", OPX6(5,0x24), ia64_print_M3}, + {"ld2.c.nc", OPX6(5,0x25), ia64_print_M3}, + {"ld4.c.nc", OPX6(5,0x26), ia64_print_M3}, + {"ld8.c.nc", OPX6(5,0x27), ia64_print_M3}, + {"ld1.c.clr.acq", OPX6(5,0x28), ia64_print_M3}, + {"ld2.c.clr.acq", OPX6(5,0x29), ia64_print_M3}, + {"ld4.c.clr.acq", OPX6(5,0x2a), ia64_print_M3}, + {"ld8.c.clr.acq", OPX6(5,0x2b), ia64_print_M3}, + {"st1", OPX6(5,0x30), ia64_print_M5}, + {"st2", OPX6(5,0x31), ia64_print_M5}, + {"st4", OPX6(5,0x32), ia64_print_M5}, + {"st8", OPX6(5,0x33), ia64_print_M5}, + {"st1.rel", OPX6(5,0x34), ia64_print_M5}, + {"st2.rel", OPX6(5,0x35), ia64_print_M5}, + {"st4.rel", OPX6(5,0x36), ia64_print_M5}, + {"st8.rel", OPX6(5,0x37), ia64_print_M5}, + {"st8.spill", OPX6(5,0x3b), ia64_print_M5}, + + /* Table 4-32 */ + {"cmpchg1.acq", OPMXX6(4,0,1,0x00), ia64_print_M16}, + {"cmpchg2.acq", OPMXX6(4,0,1,0x01), ia64_print_M16}, + {"cmpchg4.acq", OPMXX6(4,0,1,0x02), ia64_print_M16}, + {"cmpchg8.acq", OPMXX6(4,0,1,0x03), ia64_print_M16}, + {"cmpchg1.rel", OPMXX6(4,0,1,0x04), ia64_print_M16}, + {"cmpchg2.rel", OPMXX6(4,0,1,0x05), ia64_print_M16}, + {"cmpchg4.rel", OPMXX6(4,0,1,0x06), ia64_print_M16}, + {"cmpchg8.rel", OPMXX6(4,0,1,0x07), ia64_print_M16}, + {"xchg1", OPMXX6(4,0,1,0x08), ia64_print_M16}, + {"xchg2", OPMXX6(4,0,1,0x09), ia64_print_M16}, + {"xchg4", OPMXX6(4,0,1,0x0a), ia64_print_M16}, + {"xchg8", OPMXX6(4,0,1,0x0b), ia64_print_M16}, + {"fetchadd4.acq", OPMXX6(4,0,1,0x12), ia64_print_M17}, + {"fetchadd8.acq", OPMXX6(4,0,1,0x13), ia64_print_M17}, + {"fetchadd4.rel", OPMXX6(4,0,1,0x16), ia64_print_M17}, + {"fetchadd8.rel", OPMXX6(4,0,1,0x17), ia64_print_M17}, + {"getf.sig", OPMXX6(4,0,1,0x1c), ia64_print_M19}, + {"getf.exp", OPMXX6(4,0,1,0x1d), ia64_print_M19}, + {"getf.s", OPMXX6(4,0,1,0x1e), ia64_print_M19}, + {"getf.d", OPMXX6(4,0,1,0x1f), ia64_print_M19}, + + /* Table 4-33 */ + {"ldfe", OPMXX6(6,0,0,0x00), ia64_print_M6}, + {"ldf8", OPMXX6(6,0,0,0x01), ia64_print_M6}, + {"ldfs", OPMXX6(6,0,0,0x02), ia64_print_M6}, + {"ldfd", OPMXX6(6,0,0,0x03), ia64_print_M6}, + {"ldfe.s", OPMXX6(6,0,0,0x04), ia64_print_M6}, + {"ldf8.s", OPMXX6(6,0,0,0x05), ia64_print_M6}, + {"ldfs.s", OPMXX6(6,0,0,0x06), ia64_print_M6}, + {"ldfd.s", OPMXX6(6,0,0,0x07), ia64_print_M6}, + {"ldfe.a", OPMXX6(6,0,0,0x08), ia64_print_M6}, + {"ldf8.a", OPMXX6(6,0,0,0x09), ia64_print_M6}, + {"ldfs.a", OPMXX6(6,0,0,0x0a), ia64_print_M6}, + {"ldfd.a", OPMXX6(6,0,0,0x0b), ia64_print_M6}, + {"ldfe.sa", OPMXX6(6,0,0,0x0c), ia64_print_M6}, + {"ldf8.sa", OPMXX6(6,0,0,0x0d), ia64_print_M6}, + {"ldfs.sa", OPMXX6(6,0,0,0x0e), ia64_print_M6}, + {"ldfd.sa", OPMXX6(6,0,0,0x0f), ia64_print_M6}, + {"ldf.fill", OPMXX6(6,0,0,0x1b), ia64_print_M6}, + {"ldfe.c.clr", OPMXX6(6,0,0,0x20), ia64_print_M6}, + {"ldf8.c.clr", OPMXX6(6,0,0,0x21), ia64_print_M6}, + {"ldfs.c.clr", OPMXX6(6,0,0,0x22), ia64_print_M6}, + {"ldfd.c.clr", OPMXX6(6,0,0,0x23), ia64_print_M6}, + {"ldfe.c.nc", OPMXX6(6,0,0,0x24), ia64_print_M6}, + {"ldf8.c.nc", OPMXX6(6,0,0,0x25), ia64_print_M6}, + {"ldfs.c.nc", OPMXX6(6,0,0,0x26), ia64_print_M6}, + {"ldfd.c.nc", OPMXX6(6,0,0,0x27), ia64_print_M6}, + {"lfetch", OPMXX6(6,0,0,0x2c), ia64_print_M13}, + {"lfetch.excl", OPMXX6(6,0,0,0x2d), ia64_print_M13}, + {"lfetch.fault", OPMXX6(6,0,0,0x2e), ia64_print_M13}, + {"lfetch.fault.excl", OPMXX6(6,0,0,0x2f), ia64_print_M13}, + {"stfe", OPMXX6(6,0,0,0x30), ia64_print_M9}, + {"stf8", OPMXX6(6,0,0,0x31), ia64_print_M9}, + {"stfs", OPMXX6(6,0,0,0x32), ia64_print_M9}, + {"stfd", OPMXX6(6,0,0,0x33), ia64_print_M9}, + {"stf.spill", OPMXX6(6,0,0,0x3b), ia64_print_M9}, + + /* Table 4-34 */ + {"ldfe", OPMXX6(6,1,0,0x00), ia64_print_M7}, + {"ldf8", OPMXX6(6,1,0,0x01), ia64_print_M7}, + {"ldfs", OPMXX6(6,1,0,0x02), ia64_print_M7}, + {"ldfd", OPMXX6(6,1,0,0x03), ia64_print_M7}, + {"ldfe.s", OPMXX6(6,1,0,0x04), ia64_print_M7}, + {"ldf8.s", OPMXX6(6,1,0,0x05), ia64_print_M7}, + {"ldfs.s", OPMXX6(6,1,0,0x06), ia64_print_M7}, + {"ldfd.s", OPMXX6(6,1,0,0x07), ia64_print_M7}, + {"ldfe.a", OPMXX6(6,1,0,0x08), ia64_print_M7}, + {"ldf8.a", OPMXX6(6,1,0,0x09), ia64_print_M7}, + {"ldfs.a", OPMXX6(6,1,0,0x0a), ia64_print_M7}, + {"ldfd.a", OPMXX6(6,1,0,0x0b), ia64_print_M7}, + {"ldfe.sa", OPMXX6(6,1,0,0x0c), ia64_print_M7}, + {"ldf8.sa", OPMXX6(6,1,0,0x0d), ia64_print_M7}, + {"ldfs.sa", OPMXX6(6,1,0,0x0e), ia64_print_M7}, + {"ldfd.sa", OPMXX6(6,1,0,0x0f), ia64_print_M7}, + {"ldf.fill", OPMXX6(6,1,0,0x1b), ia64_print_M7}, + {"ldfe.c.clr", OPMXX6(6,1,0,0x20), ia64_print_M7}, + {"ldf8.c.clr", OPMXX6(6,1,0,0x21), ia64_print_M7}, + {"ldfs.c.clr", OPMXX6(6,1,0,0x22), ia64_print_M7}, + {"ldfd.c.clr", OPMXX6(6,1,0,0x23), ia64_print_M7}, + {"ldfe.c.nc", OPMXX6(6,1,0,0x24), ia64_print_M7}, + {"ldf8.c.nc", OPMXX6(6,1,0,0x25), ia64_print_M7}, + {"ldfs.c.nc", OPMXX6(6,1,0,0x26), ia64_print_M7}, + {"ldfd.c.nc", OPMXX6(6,1,0,0x27), ia64_print_M7}, + {"lfetch", OPMXX6(6,1,0,0x2c), ia64_print_M14}, + {"lfetch.excl", OPMXX6(6,1,0,0x2d), ia64_print_M14}, + {"lfetch.fault", OPMXX6(6,1,0,0x2e), ia64_print_M14}, + {"lfetch.fault.excl", OPMXX6(6,1,0,0x2f), ia64_print_M14}, + + /* Table 4-36 */ + {"ldfe", OPX6(7,0x00), ia64_print_M8}, + {"ldf8", OPX6(7,0x01), ia64_print_M8}, + {"ldfs", OPX6(7,0x02), ia64_print_M8}, + {"ldfd", OPX6(7,0x03), ia64_print_M8}, + {"ldfe.s", OPX6(7,0x04), ia64_print_M8}, + {"ldf8.s", OPX6(7,0x05), ia64_print_M8}, + {"ldfs.s", OPX6(7,0x06), ia64_print_M8}, + {"ldfd.s", OPX6(7,0x07), ia64_print_M8}, + {"ldfe.a", OPX6(7,0x08), ia64_print_M8}, + {"ldf8.a", OPX6(7,0x09), ia64_print_M8}, + {"ldfs.a", OPX6(7,0x0a), ia64_print_M8}, + {"ldfd.a", OPX6(7,0x0b), ia64_print_M8}, + {"ldfe.sa", OPX6(7,0x0c), ia64_print_M8}, + {"ldf8.sa", OPX6(7,0x0d), ia64_print_M8}, + {"ldfs.sa", OPX6(7,0x0e), ia64_print_M8}, + {"ldfd.sa", OPX6(7,0x0f), ia64_print_M8}, + {"ldf.fill", OPX6(7,0x1b), ia64_print_M8}, + {"ldfe.c.clr", OPX6(7,0x20), ia64_print_M8}, + {"ldf8.c.clr", OPX6(7,0x21), ia64_print_M8}, + {"ldfs.c.clr", OPX6(7,0x22), ia64_print_M8}, + {"ldfd.c.clr", OPX6(7,0x23), ia64_print_M8}, + {"ldfe.c.nc", OPX6(7,0x24), ia64_print_M8}, + {"ldf8.c.nc", OPX6(7,0x25), ia64_print_M8}, + {"ldfs.c.nc", OPX6(7,0x26), ia64_print_M8}, + {"ldfd.c.nc", OPX6(7,0x27), ia64_print_M8}, + {"lfetch", OPX6(7,0x2c), ia64_print_M15}, + {"lfetch.excl", OPX6(7,0x2d), ia64_print_M15}, + {"lfetch.fault", OPX6(7,0x2e), ia64_print_M15}, + {"lfetch.fault.excl", OPX6(7,0x2f), ia64_print_M15}, + {"stfe", OPX6(7,0x30), ia64_print_M10}, + {"stf8", OPX6(7,0x31), ia64_print_M10}, + {"stfs", OPX6(7,0x32), ia64_print_M10}, + {"stfd", OPX6(7,0x33), ia64_print_M10}, + {"stf.spill", OPX6(7,0x3b), ia64_print_M10}, + + /* Table 4-36 */ + {"ldfp8", OPMXX6(6,0,1,0x01), ia64_print_M11}, + {"ldfps", OPMXX6(6,0,1,0x02), ia64_print_M11}, + {"ldfpd", OPMXX6(6,0,1,0x03), ia64_print_M11}, + {"ldfp8.s", OPMXX6(6,0,1,0x05), ia64_print_M11}, + {"ldfps.s", OPMXX6(6,0,1,0x06), ia64_print_M11}, + {"ldfpd.s", OPMXX6(6,0,1,0x07), ia64_print_M11}, + {"ldfp8.a", OPMXX6(6,0,1,0x09), ia64_print_M11}, + {"ldfps.a", OPMXX6(6,0,1,0x0a), ia64_print_M11}, + {"ldfpd.a", OPMXX6(6,0,1,0x0b), ia64_print_M11}, + {"ldfp8.sa", OPMXX6(6,0,1,0x0d), ia64_print_M11}, + {"ldfps.sa", OPMXX6(6,0,1,0x0e), ia64_print_M11}, + {"ldfpd.sa", OPMXX6(6,0,1,0x0f), ia64_print_M11}, + {"setf.sig", OPMXX6(6,0,1,0x1c), ia64_print_M18}, + {"setf.exp", OPMXX6(6,0,1,0x1d), ia64_print_M18}, + {"setf.s", OPMXX6(6,0,1,0x1e), ia64_print_M18}, + {"setf.d", OPMXX6(6,0,1,0x1f), ia64_print_M18}, + {"ldfp8.c.clr", OPMXX6(6,0,1,0x21), ia64_print_M11}, + {"ldfps.c.clr", OPMXX6(6,0,1,0x22), ia64_print_M11}, + {"ldfpd.c.clr", OPMXX6(6,0,1,0x23), ia64_print_M11}, + {"ldfp8.c.nc", OPMXX6(6,0,1,0x25), ia64_print_M11}, + {"ldfps.c.nc", OPMXX6(6,0,1,0x26), ia64_print_M11}, + {"ldfpd.c.nc", OPMXX6(6,0,1,0x27), ia64_print_M11}, + + /* Table 4-37 */ + {"ldfp8", OPMXX6(6,1,1,0x01), ia64_print_M12}, + {"ldfps", OPMXX6(6,1,1,0x02), ia64_print_M12}, + {"ldfpd", OPMXX6(6,1,1,0x03), ia64_print_M12}, + {"ldfp8.s", OPMXX6(6,1,1,0x05), ia64_print_M12}, + {"ldfps.s", OPMXX6(6,1,1,0x06), ia64_print_M12}, + {"ldfpd.s", OPMXX6(6,1,1,0x07), ia64_print_M12}, + {"ldfp8.a", OPMXX6(6,1,1,0x09), ia64_print_M12}, + {"ldfps.a", OPMXX6(6,1,1,0x0a), ia64_print_M12}, + {"ldfpd.a", OPMXX6(6,1,1,0x0b), ia64_print_M12}, + {"ldfp8.sa", OPMXX6(6,1,1,0x0d), ia64_print_M12}, + {"ldfps.sa", OPMXX6(6,1,1,0x0e), ia64_print_M12}, + {"ldfpd.sa", OPMXX6(6,1,1,0x0f), ia64_print_M12}, + {"ldfp8.c.clr", OPMXX6(6,1,1,0x21), ia64_print_M12}, + {"ldfps.c.clr", OPMXX6(6,1,1,0x22), ia64_print_M12}, + {"ldfpd.c.clr", OPMXX6(6,1,1,0x23), ia64_print_M12}, + {"ldfp8.c.nc", OPMXX6(6,1,1,0x25), ia64_print_M12}, + {"ldfps.c.nc", OPMXX6(6,1,1,0x26), ia64_print_M12}, + {"ldfpd.c.nc", OPMXX6(6,1,1,0x27), ia64_print_M12}, + + /* Table 4-41 */ + {"chk.a.nc", OPX3(0,4), ia64_print_M22}, + {"chk.a.clr", OPX3(0,4), ia64_print_M22}, + {"chk.a.nc", OPX3(0,4), ia64_print_M23}, + {"chk.a.clr", OPX3(0,4), ia64_print_M23}, + + /* Table 4-42 */ + {"break.m", OPX3X4X2(0,0,0,0), ia64_print_M37}, + {"invala", OPX3X4X2(0,0,0,1), ia64_print_M24}, + {"fwb", OPX3X4X2(0,0,0,2), ia64_print_M24}, + {"srlz.d", OPX3X4X2(0,0,0,3), ia64_print_M24}, + {"nop.m", OPX3X4X2(0,0,1,0), ia64_print_M37}, + {"srlz.i", OPX3X4X2(0,0,1,3), ia64_print_M24}, + {"invala.e", OPX3X4X2(0,0,2,1), ia64_print_M26}, + {"mf", OPX3X4X2(0,0,2,2), ia64_print_M24}, + {"invala.e", OPX3X4X2(0,0,3,1), ia64_print_M27}, + {"mf.a", OPX3X4X2(0,0,3,2), ia64_print_M24}, + {"sync.i", OPX3X4X2(0,0,3,3), ia64_print_M24}, + {"sum", OPX3X4(0,0,4), ia64_print_M44}, + {"rum", OPX3X4(0,0,5), ia64_print_M44}, + {"ssm", OPX3X4(0,0,6), ia64_print_M44}, + {"rsm", OPX3X4(0,0,7), ia64_print_M44}, + {"mov.m", OPX3X4X2(0,0,8,2), ia64_print_M30}, + {"loadrs", OPX3X4X2(0,0,10,0), ia64_print_M24}, /* M25 */ + {"flushrs", OPX3X4X2(0,0,12,0), ia64_print_M24}, /* M25 */ + + /* Table 4-43 */ + {"chk.s.m", OPX3(1,1), ia64_print_M20}, + {"chk.s", OPX3(1,3), ia64_print_M21}, + {"alloc", OPX3(1,6), ia64_print_M34}, + + /* Table 4-44 */ + {"mov", OPX3X6(1,0,0x00), ia64_print_M42}, + {"mov", OPX3X6(1,0,0x01), ia64_print_M42}, + {"mov", OPX3X6(1,0,0x02), ia64_print_M42}, + {"mov", OPX3X6(1,0,0x03), ia64_print_M42}, + {"mov", OPX3X6(1,0,0x04), ia64_print_M42}, + {"mov", OPX3X6(1,0,0x05), ia64_print_M42}, + {"ptc.l", OPX3X6(1,0,0x09), ia64_print_M45}, + {"ptc.g", OPX3X6(1,0,0x0a), ia64_print_M45}, + {"ptc.ga", OPX3X6(1,0,0x0b), ia64_print_M45}, + {"ptr.d", OPX3X6(1,0,0x0c), ia64_print_M45}, + {"ptr.i", OPX3X6(1,0,0x0d), ia64_print_M45}, + {"itr.d", OPX3X6(1,0,0x0e), ia64_print_M42}, + {"itr.i", OPX3X6(1,0,0x0f), ia64_print_M41}, + {"mov", OPX3X6(1,0,0x10), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x11), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x12), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x13), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x14), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x15), ia64_print_M43}, + {"mov", OPX3X6(1,0,0x17), ia64_print_M43}, + {"probe.r", OPX3X6(1,0,0x18), ia64_print_M39}, + {"probe.w", OPX3X6(1,0,0x19), ia64_print_M39}, + {"thash", OPX3X6(1,0,0x1a), ia64_print_M46}, + {"ttag", OPX3X6(1,0,0x1b), ia64_print_M46}, + {"tpa", OPX3X6(1,0,0x1e), ia64_print_M46}, + {"tak", OPX3X6(1,0,0x1f), ia64_print_M46}, + {"mov", OPX3X6(1,0,0x21), ia64_print_M36}, + {"mov.m", OPX3X6(1,0,0x22), ia64_print_M31}, + {"mov", OPX3X6(1,0,0x24), ia64_print_M33}, + {"mov", OPX3X6(1,0,0x25), ia64_print_M36}, + {"mov", OPX3X6(1,0,0x29), ia64_print_M35}, + {"mov.m", OPX3X6(1,0,0x2a), ia64_print_M29}, + {"mov", OPX3X6(1,0,0x2c), ia64_print_M32}, + {"mov", OPX3X6(1,0,0x2d), ia64_print_M35}, + {"mov", OPX3X6(1,0,0x2e), ia64_print_M41}, + {"mov", OPX3X6(1,0,0x2f), ia64_print_M41}, + {"fc", OPX3X6(1,0,0x30), ia64_print_M28}, + {"probe.rw.fault", OPX3X6(1,0,0x31), ia64_print_M40}, + {"probe.r.fault", OPX3X6(1,0,0x32), ia64_print_M40}, + {"probe.w.fault", OPX3X6(1,0,0x33), ia64_print_M40}, + {"ptc.e", OPX3X6(1,0,0x34), ia64_print_M28}, + {"probe.r", OPX3X6(1,0,0x38), ia64_print_M38}, + {"probe.w", OPX3X6(1,0,0x39), ia64_print_M38}, + + {"illegal.m", 0,0, ia64_print_ill}, + {0}, +}; + +#undef OP +#undef M +#undef X +#undef X3 +#undef X6 +#undef X2 +#undef X4 + +#undef mOP +#undef mM +#undef mX +#undef mX3 +#undef mX6 +#undef mX2 +#undef mX4 + +#undef OPMXX6 +#undef OPX3 +#undef OPX6 +#undef OPX3 +#undef OPX3X4 +#undef OPX3X4X2 +#undef OPX3X6 + +#define OP(n) field(n,37,40) +#define Q(n) field(n,36,36) +#define Rb(n) field(n,36,36) +#define X2(n) field(n,34,35) +#define X(n) field(n,33,33) +#define Ra(n) field(n,33,33) +#define X6(n) field(n,27,32) +#define Ta(n) field(n,12,12) + +#define mOP OP(~0) +#define mQ Q(~0) +#define mRb Rb(~0) +#define mX2 X2(~0) +#define mX X(~0) +#define mRa Ra(~0) +#define mX6 X6(~0) +#define mTa Ta(~0) + +#define OPXX6(a,b,c) \ + OP(a)|X(b)|X6(c), mOP|mX|mX6 +#define OPXQ(a,b,c) \ + OP(a)|X(b)|Q(c), mOP|mX|mQ +#define OPX(a,b) \ + OP(a)|X(b), mOP|mX +#define OPXX2(a,b,c) \ + OP(a)|X(b)|X2(c), mOP|mX|mX2 +#define OPRaRbTa(a,b,c,d) \ + OP(a)|Ra(b)|Rb(c)|Ta(d), mOP|mRa|mRb|mTa +#define OPTa(a,b) \ + OP(a)|Ta(b), mOP|mTa + +static struct ia64_opcode F_opcodes[] = { + /* Table 4-58 */ + {"break.f", OPXX6(0,0,0x00), ia64_print_F15}, + {"nop.f", OPXX6(0,0,0x01), ia64_print_F15}, + {"fsetc", OPXX6(0,0,0x04), ia64_print_F12}, + {"fclrf", OPXX6(0,0,0x05), ia64_print_F13}, + {"fchkf", OPXX6(0,0,0x08), ia64_print_F14}, + {"fmerge.s", OPXX6(0,0,0x10), ia64_print_F9}, + {"fmerge.ns", OPXX6(0,0,0x10), ia64_print_F9}, + {"fmerge.se", OPXX6(0,0,0x10), ia64_print_F9}, + {"fmin", OPXX6(0,0,0x14), ia64_print_F8}, + {"fmax", OPXX6(0,0,0x15), ia64_print_F8}, + {"famin", OPXX6(0,0,0x16), ia64_print_F8}, + {"famax", OPXX6(0,0,0x17), ia64_print_F8}, + {"fcvt.fx", OPXX6(0,0,0x18), ia64_print_F10}, + {"fcvt.fxu", OPXX6(0,0,0x19), ia64_print_F10}, + {"fcvt.fx.trunc", OPXX6(0,0,0x1a), ia64_print_F10}, + {"fcvt.fxu.trunc", OPXX6(0,0,0x1b), ia64_print_F10}, + {"fcvt.xf", OPXX6(0,0,0x1c), ia64_print_F11}, + {"fpack", OPXX6(0,0,0x28), ia64_print_F9}, + {"fand", OPXX6(0,0,0x2c), ia64_print_F9}, + {"fandcm", OPXX6(0,0,0x2d), ia64_print_F9}, + {"for", OPXX6(0,0,0x2e), ia64_print_F9}, + {"fxor", OPXX6(0,0,0x2f), ia64_print_F9}, + {"fswap", OPXX6(0,0,0x34), ia64_print_F9}, + {"fswap.nl", OPXX6(0,0,0x35), ia64_print_F9}, + {"fswap.nr", OPXX6(0,0,0x36), ia64_print_F9}, + {"fmix.lr", OPXX6(0,0,0x39), ia64_print_F9}, + {"fmix.r", OPXX6(0,0,0x3a), ia64_print_F9}, + {"fmix.l", OPXX6(0,0,0x3b), ia64_print_F9}, + {"fsxt.r", OPXX6(0,0,0x3c), ia64_print_F9}, + {"fsxt.l", OPXX6(0,0,0x3d), ia64_print_F9}, + + /* Table 4-59 */ + {"fpmerge.s", OPXX6(1,0,0x10), ia64_print_F9}, + {"fpmerge.ns", OPXX6(1,0,0x11), ia64_print_F9}, + {"fpmerge.se", OPXX6(1,0,0x12), ia64_print_F9}, + {"fpmin", OPXX6(1,0,0x14), ia64_print_F8}, + {"fpmax", OPXX6(1,0,0x15), ia64_print_F8}, + {"fpamin", OPXX6(1,0,0x16), ia64_print_F8}, + {"fpamax", OPXX6(1,0,0x17), ia64_print_F8}, + {"fpcvt.fx", OPXX6(1,0,0x18), ia64_print_F10}, + {"fpcvt.fxu", OPXX6(1,0,0x19), ia64_print_F10}, + {"fpcvt.fx.trunc", OPXX6(1,0,0x1a), ia64_print_F10}, + {"fpcvt.fxu.trunc", OPXX6(1,0,0x1b), ia64_print_F10}, + {"fpcmp.eq", OPXX6(1,0,0x30), ia64_print_F8}, + {"fpcmp.lt", OPXX6(1,0,0x31), ia64_print_F8}, + {"fpcmp.le", OPXX6(1,0,0x32), ia64_print_F8}, + {"fpcmp.unord", OPXX6(1,0,0x33), ia64_print_F8}, + {"fpcmp.neq", OPXX6(1,0,0x34), ia64_print_F8}, + {"fpcmp.nlt", OPXX6(1,0,0x35), ia64_print_F8}, + {"fpcmp.nle", OPXX6(1,0,0x36), ia64_print_F8}, + {"fpcmp.ord", OPXX6(1,0,0x37), ia64_print_F8}, + + /* Table 4-60 */ + {"frcpa", OPXQ(0,1,0), ia64_print_F6}, + {"frsqrta", OPXQ(0,1,1), ia64_print_F7}, + {"fprcpa", OPXQ(1,1,0), ia64_print_F6}, + {"fprsqrta", OPXQ(1,1,1), ia64_print_F7}, + + /* Table 4-62 */ + {"fma", OPX(8,0), ia64_print_F1}, + {"fma.s", OPX(8,1), ia64_print_F1}, + {"fma.d", OPX(9,0), ia64_print_F1}, + {"fpma", OPX(9,1), ia64_print_F1}, + {"fms", OPX(10,0), ia64_print_F1}, + {"fms.s", OPX(10,1), ia64_print_F1}, + {"fms.d", OPX(11,0), ia64_print_F1}, + {"fpms", OPX(11,1), ia64_print_F1}, + {"fnma", OPX(12,0), ia64_print_F1}, + {"fnma.s", OPX(12,1), ia64_print_F1}, + {"fnma.d", OPX(13,0), ia64_print_F1}, + {"fpnma", OPX(13,1), ia64_print_F1}, + + /* Table 4-63 */ + {"fselect", OPX(14,0), ia64_print_F3}, + {"xma.l", OPXX2(14,1,0), ia64_print_F2}, + {"xma.hu", OPXX2(14,1,2), ia64_print_F2}, + {"xma.h", OPXX2(14,1,3), ia64_print_F2}, + + /* Table 4-64 */ + {"fcmp.eq", OPRaRbTa(4,0,0,0), ia64_print_F4}, + {"fcmp.eq.unc", OPRaRbTa(4,0,0,1), ia64_print_F4}, + {"fcmp.lt", OPRaRbTa(4,0,1,0), ia64_print_F4}, + {"fcmp.lt.unc", OPRaRbTa(4,0,1,1), ia64_print_F4}, + {"fcmp.le", OPRaRbTa(4,1,0,0), ia64_print_F4}, + {"fcmp.le.unc", OPRaRbTa(4,1,0,1), ia64_print_F4}, + {"fcmp.unord", OPRaRbTa(4,1,1,0), ia64_print_F4}, + {"fcmp.unord.unc", OPRaRbTa(4,1,1,1), ia64_print_F4}, + + /* Table 4-65 */ + {"fclass.m", OPTa(5,0), ia64_print_F5}, + {"fclass.m.unc", OPTa(5,1), ia64_print_F5}, + + {"illegal.f", 0,0, ia64_print_ill}, + {0}, +}; + +#undef OP +#undef Q +#undef X2 +#undef X +#undef X6 + +#undef mOP +#undef mQ +#undef mX2 +#undef mX +#undef mX6 + +#undef OPXX6 +#undef OPXQ +#undef OPX +#undef OPXX2 +#undef OPRaRbTa +#undef OPTa + +#define OP(n) field(n,37,40) +#define X3(n) field(n,33,35) +#define X6(n) field(n,27,32) +#define BT(n) field(n,6,8) + +#define mOP OP(~0) +#define mX3 X3(~0) +#define mX6 X6(~0) +#define mBT BT(~0) + +#define OPX6(a,b) \ + OP(a)|X6(b), mOP|mX6 +#define OPBT(a,b) \ + OP(a)|BT(b), mOP|mBT +#define OPX6BT(a,b,c) \ + OP(a)|X6(b)|BT(c), mOP|mX6|mBT + +static struct ia64_opcode B_opcodes[] = { + + /* Table 4-45 */ + {"br.cond", OPBT(4, 0), ia64_print_B1}, + {"br.wexit", OPBT(4, 2), ia64_print_B1}, + {"br.wtop", OPBT(4, 3), ia64_print_B1}, + {"br.cloop", OPBT(4, 5), ia64_print_B1}, /* B2 */ + {"br.cexit", OPBT(4, 6), ia64_print_B1}, /* B2 */ + {"br.ctop", OPBT(4, 7), ia64_print_B1}, /* B2 */ + + /* Table 4-46 */ + {"break.b", OPX6(0,0x00), ia64_print_B9}, + {"cover", OPX6(0,0x02), ia64_print_B8}, + {"clrrb", OPX6(0,0x04), ia64_print_B8}, + {"clrrb.pr", OPX6(0,0x05), ia64_print_B8}, + {"rfi", OPX6(0,0x08), ia64_print_B8}, + {"bsw.0", OPX6(0,0x0c), ia64_print_B8}, + {"bsw.1", OPX6(0,0x0d), ia64_print_B8}, + {"epc", OPX6(0,0x10), ia64_print_B8}, + + /* Table 4-47 */ + {"br.cond", OPX6BT(0,0x20,0), ia64_print_B4}, + {"br.ia", OPX6BT(0,0x20,1), ia64_print_B4}, + + /* Table 4-48 */ + {"br.ret", OPX6BT(0,0x21,4), ia64_print_B4}, + + /* Section 4.5.1.3 */ + {"br.call", OP(5),mOP, ia64_print_B3}, + + /* Section 4.5.1.5 */ + {"br.call", OP(1),mOP, ia64_print_B5}, + + /* Table 4-53 */ + {"nop.b", OPX6(2,0x00), ia64_print_B9}, + {"brp", OPX6(2,0x10), ia64_print_B7}, + {"brp.ret", OPX6(2,0x11), ia64_print_B7}, + + /* Section 4.5.2.1 */ + {"brp", OP(7),mOP, ia64_print_B6}, + + {"illegal.b", 0,0, ia64_print_ill}, + {0}, +}; + +#define OPX3X6(a,b,c) \ + OP(a)|X3(b)|X6(c), mOP|mX3|mX6 + +static struct ia64_opcode X_opcodes[] = { + + /* Table 4-67 */ + {"break.x", OPX3X6(0,0,0), ia64_print_X1}, + {"nop.x", OPX3X6(0,0,1), ia64_print_X1}, + + /* Table 4-68 */ + {"movl", OP(6),mOP, ia64_print_X2}, + + {"illegal.x", 0,0, ia64_print_ill}, + {0}, +}; + +static void +ia64_print_table(struct ia64_opcode *table, u_int64_t ins, db_addr_t loc) +{ + while (table->name) { + if ((ins & table->mask) == table->value) { + table->print(table->name, ins, loc); + return; + } + table++; + } + ia64_print_bad(0, ins, 0); +} + +static void +ia64_print_M(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + if ((ins >> 37) >= 8) + ia64_print_table(A_opcodes, ins, loc); + else + ia64_print_table(M_opcodes, ins, loc); +} + +static void +ia64_print_I(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + if ((ins >> 37) >= 8) + ia64_print_table(A_opcodes, ins, loc); + else + ia64_print_table(I_opcodes, ins, loc); + +} + +static void +ia64_print_X(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + ia64_print_table(X_opcodes, ins, loc); +} + +static void +ia64_print_B(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + ia64_print_table(B_opcodes, ins, loc); +} + +static void +ia64_print_F(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + ia64_print_table(F_opcodes, ins, loc); +} + +static void +ia64_print_bad(db_addr_t loc, u_int64_t ins, boolean_t showregs) +{ + db_printf("illegal %lx", ins); +} + +db_addr_t +db_disasm(db_addr_t loc, boolean_t altfmt) +{ + struct ia64_bundle b; + int slot; + + /* + * We encode the slot number into the low bits of the address. + */ + ia64_fetch_bundle(loc, &b); + slot = loc & 15; + + if (b.slot[slot] & 63) + db_printf("(p%ld) ", b.slot[slot] & 63); + (prints[b.template][slot])(loc, b.slot[slot], altfmt); + if (stops[b.template][slot]) + db_printf(";;\n"); + else + db_printf("\n"); + + if (b.template == 4 || b.template == 5) { + if (slot == 0) + loc += 2; + else + loc = (loc & ~15) + 16; + } else { + if (slot == 2) + loc = (loc & ~15) + 16; + else + loc++; + } + + return loc; +} diff --git a/sys/ia64/ia64/db_interface.c b/sys/ia64/ia64/db_interface.c new file mode 100644 index 0000000..e4bfc3f --- /dev/null +++ b/sys/ia64/ia64/db_interface.c @@ -0,0 +1,534 @@ +/* $FreeBSD$ */ + +/* + * Mach Operating System + * Copyright (c) 1992,1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + * + * db_interface.c,v 2.4 1991/02/05 17:11:13 mrt (CMU) + */ + +/* + * Parts of this file are derived from Mach 3: + * + * File: alpha_instruction.c + * Author: Alessandro Forin, Carnegie Mellon University + * Date: 6/92 + */ + +/* + * Interface to DDB. + */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +static jmp_buf *db_nofault = 0; +extern jmp_buf db_jmpbuf; + +extern void gdb_handle_exception __P((db_regs_t *, int)); + +#if 0 +extern char *trap_type[]; +extern int trap_types; +#endif + +int db_active; +static u_int64_t zero; +static int db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op); + +struct db_variable db_regs[] = { + /* Misc control/app registers */ +#define DB_MISC_REGS 14 /* make sure this is correct */ + + {"ip", (db_expr_t*) &ddb_regs.tf_cr_iip, FCN_NULL}, + {"psr", (db_expr_t*) &ddb_regs.tf_cr_ipsr, FCN_NULL}, + {"cr.isr", (db_expr_t*) &ddb_regs.tf_cr_isr, FCN_NULL}, + {"cr.ifa", (db_expr_t*) &ddb_regs.tf_cr_ifa, FCN_NULL}, + {"pr", (db_expr_t*) &ddb_regs.tf_pr, FCN_NULL}, + {"ar.rsc", (db_expr_t*) &ddb_regs.tf_ar_rsc, FCN_NULL}, + {"ar.pfs", (db_expr_t*) &ddb_regs.tf_ar_pfs, FCN_NULL}, + {"cr.ifs", (db_expr_t*) &ddb_regs.tf_cr_ifs, FCN_NULL}, + {"ar.bspstore", (db_expr_t*) &ddb_regs.tf_ar_bspstore, FCN_NULL}, + {"ar.rnat", (db_expr_t*) &ddb_regs.tf_ar_rnat, FCN_NULL}, + {"ar.bsp", (db_expr_t*) &ddb_regs.tf_ar_bsp, FCN_NULL}, + {"ar.unat", (db_expr_t*) &ddb_regs.tf_ar_unat, FCN_NULL}, + {"ar.ccv", (db_expr_t*) &ddb_regs.tf_ar_ccv, FCN_NULL}, + {"ar.fpsr", (db_expr_t*) &ddb_regs.tf_ar_fpsr, FCN_NULL}, + + /* Static registers */ + {"r0", (db_expr_t*) &zero, FCN_NULL}, + {"gp", (db_expr_t*) &ddb_regs.tf_r[FRAME_R1], FCN_NULL}, + {"r2", (db_expr_t*) &ddb_regs.tf_r[FRAME_R2], FCN_NULL}, + {"r3", (db_expr_t*) &ddb_regs.tf_r[FRAME_R3], FCN_NULL}, + {"r4", (db_expr_t*) &ddb_regs.tf_r[FRAME_R4], FCN_NULL}, + {"r5", (db_expr_t*) &ddb_regs.tf_r[FRAME_R5], FCN_NULL}, + {"r6", (db_expr_t*) &ddb_regs.tf_r[FRAME_R6], FCN_NULL}, + {"r7", (db_expr_t*) &ddb_regs.tf_r[FRAME_R7], FCN_NULL}, + {"r8", (db_expr_t*) &ddb_regs.tf_r[FRAME_R8], FCN_NULL}, + {"r9", (db_expr_t*) &ddb_regs.tf_r[FRAME_R9], FCN_NULL}, + {"r10", (db_expr_t*) &ddb_regs.tf_r[FRAME_R10], FCN_NULL}, + {"r11", (db_expr_t*) &ddb_regs.tf_r[FRAME_R11], FCN_NULL}, + {"sp", (db_expr_t*) &ddb_regs.tf_r[FRAME_R12], FCN_NULL}, + {"r13", (db_expr_t*) &ddb_regs.tf_r[FRAME_R13], FCN_NULL}, + {"r14", (db_expr_t*) &ddb_regs.tf_r[FRAME_R14], FCN_NULL}, + {"r15", (db_expr_t*) &ddb_regs.tf_r[FRAME_R15], FCN_NULL}, + {"r16", (db_expr_t*) &ddb_regs.tf_r[FRAME_R16], FCN_NULL}, + {"r17", (db_expr_t*) &ddb_regs.tf_r[FRAME_R17], FCN_NULL}, + {"r18", (db_expr_t*) &ddb_regs.tf_r[FRAME_R18], FCN_NULL}, + {"r19", (db_expr_t*) &ddb_regs.tf_r[FRAME_R19], FCN_NULL}, + {"r20", (db_expr_t*) &ddb_regs.tf_r[FRAME_R20], FCN_NULL}, + {"r21", (db_expr_t*) &ddb_regs.tf_r[FRAME_R21], FCN_NULL}, + {"r22", (db_expr_t*) &ddb_regs.tf_r[FRAME_R22], FCN_NULL}, + {"r23", (db_expr_t*) &ddb_regs.tf_r[FRAME_R23], FCN_NULL}, + {"r24", (db_expr_t*) &ddb_regs.tf_r[FRAME_R24], FCN_NULL}, + {"r25", (db_expr_t*) &ddb_regs.tf_r[FRAME_R25], FCN_NULL}, + {"r26", (db_expr_t*) &ddb_regs.tf_r[FRAME_R26], FCN_NULL}, + {"r27", (db_expr_t*) &ddb_regs.tf_r[FRAME_R27], FCN_NULL}, + {"r28", (db_expr_t*) &ddb_regs.tf_r[FRAME_R28], FCN_NULL}, + {"r29", (db_expr_t*) &ddb_regs.tf_r[FRAME_R29], FCN_NULL}, + {"r30", (db_expr_t*) &ddb_regs.tf_r[FRAME_R30], FCN_NULL}, + {"r31", (db_expr_t*) &ddb_regs.tf_r[FRAME_R31], FCN_NULL}, + + /* Stacked registers */ + {"r32", (db_expr_t*) 32, db_get_rse_reg}, + {"r33", (db_expr_t*) 33, db_get_rse_reg}, + {"r34", (db_expr_t*) 34, db_get_rse_reg}, + {"r35", (db_expr_t*) 35, db_get_rse_reg}, + {"r36", (db_expr_t*) 36, db_get_rse_reg}, + {"r37", (db_expr_t*) 37, db_get_rse_reg}, + {"r38", (db_expr_t*) 38, db_get_rse_reg}, + {"r39", (db_expr_t*) 39, db_get_rse_reg}, + {"r40", (db_expr_t*) 40, db_get_rse_reg}, + {"r41", (db_expr_t*) 41, db_get_rse_reg}, + {"r42", (db_expr_t*) 42, db_get_rse_reg}, + {"r43", (db_expr_t*) 43, db_get_rse_reg}, + {"r44", (db_expr_t*) 44, db_get_rse_reg}, + {"r45", (db_expr_t*) 45, db_get_rse_reg}, + {"r46", (db_expr_t*) 46, db_get_rse_reg}, + {"r47", (db_expr_t*) 47, db_get_rse_reg}, + {"r48", (db_expr_t*) 48, db_get_rse_reg}, + {"r49", (db_expr_t*) 49, db_get_rse_reg}, + {"r50", (db_expr_t*) 50, db_get_rse_reg}, + {"r51", (db_expr_t*) 51, db_get_rse_reg}, + {"r52", (db_expr_t*) 52, db_get_rse_reg}, + {"r53", (db_expr_t*) 53, db_get_rse_reg}, + {"r54", (db_expr_t*) 54, db_get_rse_reg}, + {"r55", (db_expr_t*) 55, db_get_rse_reg}, + {"r56", (db_expr_t*) 56, db_get_rse_reg}, + {"r57", (db_expr_t*) 57, db_get_rse_reg}, + {"r58", (db_expr_t*) 58, db_get_rse_reg}, + {"r59", (db_expr_t*) 59, db_get_rse_reg}, + {"r60", (db_expr_t*) 60, db_get_rse_reg}, + {"r61", (db_expr_t*) 61, db_get_rse_reg}, + {"r62", (db_expr_t*) 62, db_get_rse_reg}, + {"r63", (db_expr_t*) 63, db_get_rse_reg}, + {"r64", (db_expr_t*) 64, db_get_rse_reg}, + {"r65", (db_expr_t*) 65, db_get_rse_reg}, + {"r66", (db_expr_t*) 66, db_get_rse_reg}, + {"r67", (db_expr_t*) 67, db_get_rse_reg}, + {"r68", (db_expr_t*) 68, db_get_rse_reg}, + {"r69", (db_expr_t*) 69, db_get_rse_reg}, + {"r70", (db_expr_t*) 70, db_get_rse_reg}, + {"r71", (db_expr_t*) 71, db_get_rse_reg}, + {"r72", (db_expr_t*) 72, db_get_rse_reg}, + {"r73", (db_expr_t*) 73, db_get_rse_reg}, + {"r74", (db_expr_t*) 74, db_get_rse_reg}, + {"r75", (db_expr_t*) 75, db_get_rse_reg}, + {"r76", (db_expr_t*) 76, db_get_rse_reg}, + {"r77", (db_expr_t*) 77, db_get_rse_reg}, + {"r78", (db_expr_t*) 78, db_get_rse_reg}, + {"r79", (db_expr_t*) 79, db_get_rse_reg}, + {"r80", (db_expr_t*) 80, db_get_rse_reg}, + {"r81", (db_expr_t*) 81, db_get_rse_reg}, + {"r82", (db_expr_t*) 82, db_get_rse_reg}, + {"r83", (db_expr_t*) 83, db_get_rse_reg}, + {"r84", (db_expr_t*) 84, db_get_rse_reg}, + {"r85", (db_expr_t*) 85, db_get_rse_reg}, + {"r86", (db_expr_t*) 86, db_get_rse_reg}, + {"r87", (db_expr_t*) 87, db_get_rse_reg}, + {"r88", (db_expr_t*) 88, db_get_rse_reg}, + {"r89", (db_expr_t*) 89, db_get_rse_reg}, + {"r90", (db_expr_t*) 90, db_get_rse_reg}, + {"r91", (db_expr_t*) 91, db_get_rse_reg}, + {"r92", (db_expr_t*) 92, db_get_rse_reg}, + {"r93", (db_expr_t*) 93, db_get_rse_reg}, + {"r94", (db_expr_t*) 94, db_get_rse_reg}, + {"r95", (db_expr_t*) 95, db_get_rse_reg}, + {"r96", (db_expr_t*) 96, db_get_rse_reg}, + {"r97", (db_expr_t*) 97, db_get_rse_reg}, + {"r98", (db_expr_t*) 98, db_get_rse_reg}, + {"r99", (db_expr_t*) 99, db_get_rse_reg}, + {"r100", (db_expr_t*) 100, db_get_rse_reg}, + {"r101", (db_expr_t*) 101, db_get_rse_reg}, + {"r102", (db_expr_t*) 102, db_get_rse_reg}, + {"r103", (db_expr_t*) 103, db_get_rse_reg}, + {"r104", (db_expr_t*) 104, db_get_rse_reg}, + {"r105", (db_expr_t*) 105, db_get_rse_reg}, + {"r106", (db_expr_t*) 106, db_get_rse_reg}, + {"r107", (db_expr_t*) 107, db_get_rse_reg}, + {"r108", (db_expr_t*) 108, db_get_rse_reg}, + {"r109", (db_expr_t*) 109, db_get_rse_reg}, + {"r110", (db_expr_t*) 110, db_get_rse_reg}, + {"r111", (db_expr_t*) 111, db_get_rse_reg}, + {"r112", (db_expr_t*) 112, db_get_rse_reg}, + {"r113", (db_expr_t*) 113, db_get_rse_reg}, + {"r114", (db_expr_t*) 114, db_get_rse_reg}, + {"r115", (db_expr_t*) 115, db_get_rse_reg}, + {"r116", (db_expr_t*) 116, db_get_rse_reg}, + {"r117", (db_expr_t*) 117, db_get_rse_reg}, + {"r118", (db_expr_t*) 118, db_get_rse_reg}, + {"r119", (db_expr_t*) 119, db_get_rse_reg}, + {"r120", (db_expr_t*) 120, db_get_rse_reg}, + {"r121", (db_expr_t*) 121, db_get_rse_reg}, + {"r122", (db_expr_t*) 122, db_get_rse_reg}, + {"r123", (db_expr_t*) 123, db_get_rse_reg}, + {"r124", (db_expr_t*) 124, db_get_rse_reg}, + {"r125", (db_expr_t*) 125, db_get_rse_reg}, + {"r126", (db_expr_t*) 126, db_get_rse_reg}, + {"r127", (db_expr_t*) 127, db_get_rse_reg}, +}; +struct db_variable *db_eregs = db_regs + sizeof(db_regs)/sizeof(db_regs[0]); + +static int +rse_slot(u_int64_t *bsp) +{ + return ((u_int64_t) bsp >> 3) & 0x3f; +} + +/* + * Return the address of register regno (regno >= 32) given that bsp + * points at the base of the register stack frame. + */ +static u_int64_t * +rse_register_address(u_int64_t *bsp, int regno) +{ + int off = regno - 32; + u_int64_t rnats = (rse_slot(bsp) + off) / 63; + u_int64_t *p = bsp + off + rnats; + return p; +} + +static u_int64_t * +rse_previous_frame(u_int64_t *bsp, int sof) +{ + int slot = rse_slot(bsp); + int rnats = 0; + int count = sof; + + while (count > slot) { + count -= 63; + rnats++; + slot = 63; + } + return bsp - sof - rnats; +} + +static int +db_get_rse_reg(struct db_variable *vp, db_expr_t *valuep, int op) +{ + int sof = ddb_regs.tf_cr_ifs & 0xff; + int regno = (db_expr_t) vp->valuep; + u_int64_t *bsp = (u_int64_t *) ddb_regs.tf_ar_bsp; + u_int64_t *reg; + + if (regno - 32 >= sof) { + if (op == DB_VAR_GET) + *valuep = 0xdeadbeefdeadbeef; + } else { + bsp = rse_previous_frame(bsp, sof); + reg = rse_register_address(bsp, regno); + if (op == DB_VAR_GET) + *valuep = *reg; + else + *reg = *valuep; + } + + return 0; +} + +/* + * Print trap reason. + */ +static void +ddbprinttrap(int vector) +{ + + /* XXX Implement. */ + + printf("ddbprinttrap(%d)\n", vector); +} + +/* + * ddb_trap - field a kernel trap + */ +int +kdb_trap(int vector, struct trapframe *regs) +{ + int ddb_mode = !(boothowto & RB_GDB); + int s; + + /* + * Don't bother checking for usermode, since a benign entry + * by the kernel (call to Debugger() or a breakpoint) has + * already checked for usermode. If neither of those + * conditions exist, something Bad has happened. + */ + + if (vector != IA64_VEC_BREAK) { +#if 0 + if (ddb_mode) { + db_printf("ddbprinttrap from 0x%lx\n", /* XXX */ + regs->tf_regs[FRAME_PC]); + ddbprinttrap(a0, a1, a2, entry); + /* + * Tell caller "We did NOT handle the trap." + * Caller should panic, or whatever. + */ + return (0); + } +#endif + if (db_nofault) { + jmp_buf *no_fault = db_nofault; + db_nofault = 0; + longjmp(*no_fault, 1); + } + } + + /* + * XXX Should switch to DDB's own stack, here. + */ + + ddb_regs = *regs; + + /* + * XXX pretend that registers outside the current frame don't exist. + */ + db_eregs = db_regs + DB_MISC_REGS + 32 + (ddb_regs.tf_cr_ifs & 0xff); + + __asm __volatile("flushrs"); /* so we can look at them */ + + s = splhigh(); + +#if 0 + db_printf("stopping %x\n", PCPU_GET(other_cpus)); + stop_cpus(PCPU_GET(other_cpus)); + db_printf("stopped_cpus=%x\n", stopped_cpus); +#endif + + db_active++; + + if (ddb_mode) { + cndbctl(TRUE); /* DDB active, unblank video */ + db_trap(vector, 0); /* Where the work happens */ + cndbctl(FALSE); /* DDB inactive */ + } else + gdb_handle_exception(&ddb_regs, vector); + + db_active--; + +#if 0 + restart_cpus(stopped_cpus); +#endif + + splx(s); + + *regs = ddb_regs; + + /* + * Tell caller "We HAVE handled the trap." + */ + return (1); +} + +/* + * Read bytes from kernel address space for debugger. + */ +void +db_read_bytes(addr, size, data) + vm_offset_t addr; + register size_t size; + register char *data; +{ + register char *src; + + db_nofault = &db_jmpbuf; + + src = (char *)addr; + while (size-- > 0) + *data++ = *src++; + + db_nofault = 0; +} + +/* + * Write bytes to kernel address space for debugger. + */ +void +db_write_bytes(addr, size, data) + vm_offset_t addr; + register size_t size; + register char *data; +{ + register char *dst; + + db_nofault = &db_jmpbuf; + + dst = (char *)addr; + while (size-- > 0) + *dst++ = *data++; + + db_nofault = 0; +} + +void +Debugger(const char* msg) +{ + printf("%s\n", msg); + __asm("break 0x80100"); +} + +u_long +db_register_value(regs, regno) + db_regs_t *regs; + int regno; +{ + + if (regno > 127 || regno < 0) { + db_printf(" **** STRANGE REGISTER NUMBER %d **** ", regno); + return (0); + } + + if (regno == 0) + return (0); + + if (regno < 32) { + return (regs->tf_r[regno - 1]); + } else { + int sof = ddb_regs.tf_cr_ifs & 0xff; + u_int64_t *bsp = (u_int64_t *) ddb_regs.tf_ar_bsp; + u_int64_t *reg; + + if (regno - 32 >= sof) { + return 0xdeadbeefdeadbeef; + } else { + bsp = rse_previous_frame(bsp, sof); + reg = rse_register_address(bsp, regno); + return *reg; + } + } +} + +#if defined(KTR) + +struct tstate { + int cur; + int first; +}; +static struct tstate tstate; +static int db_mach_vtrace(void); + +DB_COMMAND(tbuf, db_mach_tbuf) +{ + + /* + * We know that ktr_idx is the oldest entry, so don't go futzing + * around with timespecs unnecessarily. + */ + tstate.first = ktr_idx; + if ((tstate.cur = ktr_idx - 1) < 0) + tstate.cur = KTR_ENTRIES - 1; + + db_mach_vtrace(); + + return; +} + +DB_COMMAND(tall, db_mach_tall) +{ + int c; + + db_mach_tbuf(addr, have_addr, count, modif); + while (db_mach_vtrace()) { + c = cncheckc(); + if (c != -1) + break; + } + + return; +} + +DB_COMMAND(tnext, db_mach_tnext) +{ + db_mach_vtrace(); +} + +static int +db_mach_vtrace(void) +{ + struct ktr_entry *kp; + + if (tstate.cur == tstate.first) { + db_printf("--- End of trace buffer ---\n"); + return (0); + } + + kp = &ktr_buf[tstate.cur]; + + db_printf("%d: %4d.%06ld: ", tstate.cur, kp->ktr_tv.tv_sec, + kp->ktr_tv.tv_nsec / 1000); +#ifdef KTR_EXTEND + db_printf("cpu%d %s.%d\t%s", kp->ktr_cpu, kp->ktr_filename, + kp->ktr_line, kp->ktr_desc); +#else + db_printf(kp->ktr_desc, kp->ktr_parm1, kp->ktr_parm2, kp->ktr_parm3, + kp->ktr_parm4, kp->ktr_parm5); +#endif + db_printf("\n"); + tstate.first &= ~0x80000000; + if (--tstate.cur < 0) + tstate.cur = KTR_ENTRIES - 1; + + return (1); +} + +#endif diff --git a/sys/ia64/ia64/db_trace.c b/sys/ia64/ia64/db_trace.c new file mode 100644 index 0000000..8b0fba7 --- /dev/null +++ b/sys/ia64/ia64/db_trace.c @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * 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 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 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. + * + * $FreeBSD$ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +void +db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) +{ +} diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c index a05bcb4..0a5e43a 100644 --- a/sys/ia64/ia64/genassym.c +++ b/sys/ia64/ia64/genassym.c @@ -112,6 +112,7 @@ ASSYM(U_PCB_UNAT, offsetof(struct user, u_pcb.pcb_unat)); ASSYM(U_PCB_RNAT, offsetof(struct user, u_pcb.pcb_rnat)); ASSYM(U_PCB_PR, offsetof(struct user, u_pcb.pcb_pr)); +ASSYM(U_PCB_SCHEDNEST, offsetof(struct user, u_pcb.pcb_onfault)); ASSYM(U_PCB_ONFAULT, offsetof(struct user, u_pcb.pcb_onfault)); ASSYM(UC_MCONTEXT_MC_AR_BSP, offsetof(ucontext_t, uc_mcontext.mc_ar_bsp)); diff --git a/sys/ia64/ia64/ia64-gdbstub.c b/sys/ia64/ia64/ia64-gdbstub.c new file mode 100644 index 0000000..4333af2 --- /dev/null +++ b/sys/ia64/ia64/ia64-gdbstub.c @@ -0,0 +1,588 @@ +/* $FreeBSD$ */ +/**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or its performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +/**************************************************************************** + * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ + * + * Module name: remcom.c $ + * Revision: 1.34 $ + * Date: 91/03/09 12:29:49 $ + * Contributor: Lake Stevens Instrument Division$ + * + * Description: low level support for gdb debugger. $ + * + * Considerations: only works on target hardware $ + * + * Written by: Glenn Engel $ + * ModuleState: Experimental $ + * + * NOTES: See Below $ + * + * Modified for FreeBSD by Stu Grossman. + * + * To enable debugger support, two things need to happen. One, a + * call to set_debug_traps() is necessary in order to allow any breakpoints + * or error conditions to be properly intercepted and reported to gdb. + * Two, a breakpoint needs to be generated to begin communication. This + * is most easily accomplished by a call to breakpoint(). Breakpoint() + * simulates a breakpoint by executing a trap #1. + * + * The external function exceptionHandler() is + * used to attach a specific handler to a specific 386 vector number. + * It should use the same privilege level it runs at. It should + * install it as an interrupt gate so that interrupts are masked + * while the handler runs. + * Also, need to assign exceptionHook and oldExceptionHook. + * + * Because gdb will sometimes write to the stack area to execute function + * calls, this program cannot rely on using the supervisor stack so it + * uses its own stack area reserved in the int array remcomStack. + * + ************* + * + * The following gdb commands are supported: + * + * command function Return value + * + * g return the value of the CPU registers hex data or ENN + * G set the value of the CPU registers OK or ENN + * + * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN + * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN + * + * c Resume at current address SNN ( signal NN) + * cAA..AA Continue at address AA..AA SNN + * + * s Step one instruction SNN + * sAA..AA Step one instruction from AA..AA SNN + * + * k kill + * + * ? What was the last sigval ? SNN (signal NN) + * + * D detach OK + * + * All commands and responses are sent with a packet which includes a + * checksum. A packet consists of + * + * $#. + * + * where + * :: + * :: < two hex digits computed as modulo 256 sum of > + * + * When a packet is received, it is first acknowledged with either '+' or '-'. + * '+' indicates a successful transfer. '-' indicates a failed transfer. + * + * Example: + * + * Host: Reply: + * $m0,10#2a +$00010203040506070809101112131415#42 + * + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +/* #include "sio.h" */ +#include "opt_ddb.h" + +#include "sio.h" + +#if NSIO == 0 +void +gdb_handle_exception (db_regs_t *raw_regs, int type, int code) +{ +} +#else +/************************************************************************/ + +void gdb_handle_exception (db_regs_t *, int); + +extern jmp_buf db_jmpbuf; + +/************************************************************************/ +/* BUFMAX defines the maximum number of characters in inbound/outbound buffers*/ +/* at least NUMREGBYTES*2 are needed for register packets */ +#define BUFMAX 1500 + +/* Create private copies of common functions used by the stub. This prevents + nasty interactions between app code and the stub (for instance if user steps + into strlen, etc..) */ +/* XXX this is fairly bogus. strlen() and strcpy() should be reentrant, + and are reentrant under FreeBSD. In any case, our versions should not + be named the same as the standard versions, so that the address `strlen' + is unambiguous... */ + +static int +strlen (const char *s) +{ + const char *s1 = s; + + while (*s1++ != '\000'); + + return s1 - s; +} + +static char * +strcpy (char *dst, const char *src) +{ + char *retval = dst; + + while ((*dst++ = *src++) != '\000'); + + return retval; +} + +/* XXX sio always uses its major with minor 0 no matter what we specify. */ +#define REMOTE_DEV 0 + +static int +putDebugChar (int c) /* write a single character */ +{ + return 1; +} + +static int +getDebugChar (void) /* read and return a single char */ +{ + return 0; +} + +static const char hexchars[]="0123456789abcdef"; + +static int +hex(char ch) +{ + if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); + if ((ch >= '0') && (ch <= '9')) return (ch-'0'); + if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); + return (-1); +} + +/* scan for the sequence $# */ +static void +getpacket (char *buffer) +{ + unsigned char checksum; + unsigned char xmitcsum; + int i; + int count; + unsigned char ch; + + do + { + /* wait around for the start character, ignore all other characters */ + + while ((ch = (getDebugChar () & 0x7f)) != '$'); + + checksum = 0; + xmitcsum = -1; + + count = 0; + + /* now, read until a # or end of buffer is found */ + + while (count < BUFMAX) + { + ch = getDebugChar () & 0x7f; + if (ch == '#') + break; + checksum = checksum + ch; + buffer[count] = ch; + count = count + 1; + } + buffer[count] = 0; + + if (ch == '#') + { + xmitcsum = hex (getDebugChar () & 0x7f) << 4; + xmitcsum += hex (getDebugChar () & 0x7f); + + if (checksum != xmitcsum) + putDebugChar ('-'); /* failed checksum */ + else + { + putDebugChar ('+'); /* successful transfer */ + /* if a sequence char is present, reply the sequence ID */ + if (buffer[2] == ':') + { + putDebugChar (buffer[0]); + putDebugChar (buffer[1]); + + /* remove sequence chars from buffer */ + + count = strlen (buffer); + for (i=3; i <= count; i++) + buffer[i-3] = buffer[i]; + } + } + } + } + while (checksum != xmitcsum); + + if (strlen(buffer) >= BUFMAX) + panic("kgdb: buffer overflow"); +} + +/* send the packet in buffer. */ + +static void +putpacket (char *buffer) +{ + unsigned char checksum; + int count; + unsigned char ch; + + if (strlen(buffer) >= BUFMAX) + panic("kgdb: buffer overflow"); + + /* $#. */ + do + { +/* + * This is a non-standard hack to allow use of the serial console for + * operation as well as debugging. Simply turn on 'remotechat' in gdb. + * + * This extension is not part of the Cygnus protocol, is kinda gross, + * but gets the job done. + */ +#ifdef GDB_REMOTE_CHAT + putDebugChar ('|'); + putDebugChar ('|'); + putDebugChar ('|'); + putDebugChar ('|'); +#endif + putDebugChar ('$'); + checksum = 0; + count = 0; + + while ((ch=buffer[count]) != 0) + { + putDebugChar (ch); + checksum += ch; + count += 1; + } + + putDebugChar ('#'); + putDebugChar (hexchars[checksum >> 4]); + putDebugChar (hexchars[checksum & 0xf]); + } + while ((getDebugChar () & 0x7f) != '+'); +} + +static char remcomInBuffer[BUFMAX]; +static char remcomOutBuffer[BUFMAX]; + +static int +get_char (vm_offset_t addr) +{ + char data; + + if (setjmp (db_jmpbuf)) + return -1; + + db_read_bytes (addr, 1, &data); + + return data & 0xff; +} + +static int +set_char (vm_offset_t addr, int val) +{ + char data; + + if (setjmp (db_jmpbuf)) + return -1; + + data = val; + + db_write_bytes (addr, 1, &data); + return 0; +} + +/* convert the memory pointed to by mem into hex, placing result in buf */ +/* return a pointer to the last char put in buf (null) */ + +static char * +mem2hex (vm_offset_t mem, char *buf, int count) +{ + int i; + int ch; + + for (i=0;i> 4]; + *buf++ = hexchars[ch % 16]; + } + *buf = 0; + return(buf); +} + +/* convert the hex array pointed to by buf into binary to be placed in mem */ +/* return a pointer to the character AFTER the last byte written */ +static char * +hex2mem (char *buf, vm_offset_t mem, int count) +{ + int i; + int ch; + int rv; + + for (i=0;i=0) + { + *intValue = (*intValue <<4) | hexValue; + numChars ++; + } + else + break; + + (*ptr)++; + } + + return (numChars); +} + +#define NUMREGBYTES (sizeof registers) +#define PC 64 +#define SP 30 +#define FP 15 +#define VFP 65 +#define NUM_REGS 66 + +/* + * This function does all command procesing for interfacing to gdb. + */ +void +gdb_handle_exception (db_regs_t *raw_regs, int vector) +{ +#if 0 + int sigval; + long addr, length; + char * ptr; + struct alpharegs { + u_int64_t r[32]; + u_int64_t f[32]; + u_int64_t pc, vfp; + }; + static struct alpharegs registers; + int i; + + clear_single_step(raw_regs); + + bzero(®isters, sizeof registers); + + /* + * Map trapframe to registers. + * Ignore float regs for now. + */ + for (i = 0; i < FRAME_SIZE; i++) + if (tf2gdb[i] >= 0) + registers.r[tf2gdb[i]] = raw_regs->tf_regs[i]; + registers.pc = raw_regs->tf_regs[FRAME_PC]; + + /* reply to host that an exception has occurred */ + sigval = computeSignal (type, code); + ptr = remcomOutBuffer; + + *ptr++ = 'T'; + *ptr++ = hexchars[sigval >> 4]; + *ptr++ = hexchars[sigval & 0xf]; + + *ptr++ = hexchars[PC >> 4]; + *ptr++ = hexchars[PC & 0xf]; + *ptr++ = ':'; + ptr = mem2hex ((vm_offset_t)®isters.pc, ptr, 8); + *ptr++ = ';'; + + *ptr++ = hexchars[FP >> 4]; + *ptr++ = hexchars[FP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex ((vm_offset_t)®isters.r[FP], ptr, 8); + *ptr++ = ';'; + + *ptr++ = hexchars[SP >> 4]; + *ptr++ = hexchars[SP & 0xf]; + *ptr++ = ':'; + ptr = mem2hex ((vm_offset_t)®isters.r[SP], ptr, 8); + *ptr++ = ';'; + + *ptr++ = 0; + + putpacket (remcomOutBuffer); + + while (1) + { + remcomOutBuffer[0] = 0; + + getpacket (remcomInBuffer); + switch (remcomInBuffer[0]) + { + case '?': + remcomOutBuffer[0] = 'S'; + remcomOutBuffer[1] = hexchars[sigval >> 4]; + remcomOutBuffer[2] = hexchars[sigval % 16]; + remcomOutBuffer[3] = 0; + break; + + case 'D': /* detach; say OK and turn off gdb */ + putpacket(remcomOutBuffer); + boothowto &= ~RB_GDB; + return; + + case 'k': + prom_halt(); + /*NOTREACHED*/ + break; + + case 'g': /* return the value of the CPU registers */ + mem2hex ((vm_offset_t)®isters, remcomOutBuffer, NUMREGBYTES); + break; + + case 'G': /* set the value of the CPU registers - return OK */ + hex2mem (&remcomInBuffer[1], (vm_offset_t)®isters, NUMREGBYTES); + strcpy (remcomOutBuffer, "OK"); + break; + + case 'P': /* Set the value of one register */ + { + long regno; + + ptr = &remcomInBuffer[1]; + + if (hexToInt (&ptr, ®no) + && *ptr++ == '=' + && regno < NUM_REGS) + { + hex2mem (ptr, (vm_offset_t)®isters + regno * 8, 8); + strcpy(remcomOutBuffer,"OK"); + } + else + strcpy (remcomOutBuffer, "P01"); + break; + } + case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ + /* Try to read %x,%x. */ + + ptr = &remcomInBuffer[1]; + + if (hexToInt (&ptr, &addr) + && *(ptr++) == ',' + && hexToInt (&ptr, &length)) + { + if (mem2hex((vm_offset_t) addr, remcomOutBuffer, length) == NULL) + strcpy (remcomOutBuffer, "E03"); + break; + } + else + strcpy (remcomOutBuffer, "E01"); + break; + + case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ + + /* Try to read '%x,%x:'. */ + + ptr = &remcomInBuffer[1]; + + if (hexToInt(&ptr,&addr) + && *(ptr++) == ',' + && hexToInt(&ptr, &length) + && *(ptr++) == ':') + { + if (hex2mem(ptr, (vm_offset_t) addr, length) == NULL) + strcpy (remcomOutBuffer, "E03"); + else + strcpy (remcomOutBuffer, "OK"); + } + else + strcpy (remcomOutBuffer, "E02"); + break; + + /* cAA..AA Continue at address AA..AA(optional) */ + /* sAA..AA Step one instruction from AA..AA(optional) */ + case 'c' : + case 's' : + /* try to read optional parameter, pc unchanged if no parm */ + + ptr = &remcomInBuffer[1]; + if (hexToInt(&ptr,&addr)) + registers.pc = addr; + + /* + * Map gdb registers back to trapframe (ignoring fp regs). + */ + for (i = 0; i < NUM_REGS; i++) + if (gdb2tf[i] >= 0) + raw_regs->tf_regs[gdb2tf[i]] = registers.r[i]; + raw_regs->tf_regs[FRAME_PC] = registers.pc; + + if (remcomInBuffer[0] == 's') + if (!set_single_step(raw_regs)) + printf("Can't set single step breakpoint\n"); + + return; + + } /* switch */ + + /* reply to the request */ + putpacket (remcomOutBuffer); + } +#endif +} +#endif /* NSIO > 0 */ diff --git a/sys/ia64/ia64/ipl_funcs.c b/sys/ia64/ia64/ipl_funcs.c index baf6cb2..4a4a4e0 100644 --- a/sys/ia64/ia64/ipl_funcs.c +++ b/sys/ia64/ia64/ipl_funcs.c @@ -50,7 +50,7 @@ unsigned int tty_imask; /* XXX */ static void swi_net(void); void (*netisrs[32]) __P((void)); -swihand_t *ihandlers[32] = { /* software interrupts */ +swihand_t *shandlers[32] = { /* software interrupts */ swi_null, swi_net, swi_null, swi_null, swi_null, softclock, swi_null, swi_null, swi_null, swi_null, swi_null, swi_null, @@ -62,23 +62,6 @@ swihand_t *ihandlers[32] = { /* software interrupts */ }; u_int32_t netisr; -u_int32_t ipending; -u_int32_t idelayed; - -#define getcpl() (alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) - - -static void atomic_setbit(u_int32_t* p, u_int32_t bit) -{ - *p |= bit; -} - -static u_int32_t atomic_readandclear(u_int32_t* p) -{ - u_int32_t v = *p; - *p = 0; - return v; -} void swi_null() @@ -96,7 +79,7 @@ swi_generic() static void swi_net() { - u_int32_t bits = atomic_readandclear(&netisr); + u_int32_t bits = atomic_readandclear_32(&netisr); int i; for (i = 0; i < 32; i++) { @@ -105,118 +88,3 @@ swi_net() bits >>= 1; } } - -void -do_sir() -{ - u_int32_t pend; - int i; - - mtx_enter(&Giant, MTX_DEF); - - atomic_add_int(&PCPU_GET(intr_nesting_level), 1); - splsoft(); - while ((pend = atomic_readandclear(&ipending)) != 0) { - for (i = 0; pend && i < 32; i++) { - if (pend & (1 << i)) { - if (ihandlers[i] == swi_generic) - swi_dispatcher(i); - else - ihandlers[i](); - pend &= ~(1 << i); - } - } - } - atomic_subtract_int(&PCPU_GET(intr_nesting_level), 1); - - mtx_exit(&Giant, MTX_DEF); -} - -#define GENSET(name, ptr, bit) \ - \ -void name(void) \ -{ \ - atomic_setbit(ptr, bit); \ -} - -GENSET(setdelayed, &ipending, atomic_readandclear(&idelayed)) -GENSET(setsofttty, &ipending, 1 << SWI_TTY) -GENSET(setsoftnet, &ipending, 1 << SWI_NET) -GENSET(setsoftcamnet, &ipending, 1 << SWI_CAMNET) -GENSET(setsoftcambio, &ipending, 1 << SWI_CAMBIO) -GENSET(setsoftvm, &ipending, 1 << SWI_VM) -GENSET(setsofttq, &ipending, 1 << SWI_TQ) -GENSET(setsoftclock, &ipending, 1 << SWI_CLOCK) - -GENSET(schedsofttty, &idelayed, 1 << SWI_TTY) -GENSET(schedsoftnet, &idelayed, 1 << SWI_NET) -GENSET(schedsoftcamnet, &idelayed, 1 << SWI_CAMNET) -GENSET(schedsoftcambio, &idelayed, 1 << SWI_CAMBIO) -GENSET(schedsoftvm, &idelayed, 1 << SWI_VM) -GENSET(schedsofttq, &idelayed, 1 << SWI_TQ) -GENSET(schedsoftclock, &idelayed, 1 << SWI_CLOCK) - -#ifdef INVARIANT_SUPPORT - -#define SPLASSERT_IGNORE 0 -#define SPLASSERT_LOG 1 -#define SPLASSERT_PANIC 2 - -static int splassertmode = SPLASSERT_LOG; -SYSCTL_INT(_kern, OID_AUTO, splassertmode, CTLFLAG_RW, - &splassertmode, 0, "Set the mode of SPLASSERT"); - -static void -init_splassertmode(void *ignored) -{ - TUNABLE_INT_FETCH("kern.splassertmode", 0, splassertmode); -} -SYSINIT(param, SI_SUB_TUNABLES, SI_ORDER_ANY, init_splassertmode, NULL); - -static void -splassertfail(char *str, const char *msg, char *name, int level) -{ - switch (splassertmode) { - case SPLASSERT_IGNORE: - break; - case SPLASSERT_LOG: - printf(str, msg, name, level); - printf("\n"); - break; - case SPLASSERT_PANIC: - panic(str, msg, name, level); - break; - } -} - -#define GENSPLASSERT(name, pri) \ -void \ -name##assert(const char *msg) \ -{ \ - u_int cpl; \ - \ - cpl = getcpl(); \ - if (cpl < ALPHA_PSL_IPL_##pri) \ - splassertfail("%s: not %s, cpl == %#x", \ - msg, __XSTRING(name) + 3, cpl); \ -} -#else -#define GENSPLASSERT(name, pri) -#endif - -GENSPLASSERT(splbio, IO) -GENSPLASSERT(splcam, IO) -GENSPLASSERT(splclock, CLOCK) -GENSPLASSERT(splhigh, HIGH) -GENSPLASSERT(splimp, IO) -GENSPLASSERT(splnet, IO) -GENSPLASSERT(splsoftcam, SOFT) -GENSPLASSERT(splsoftcambio, SOFT) /* XXX no corresponding spl for alpha */ -GENSPLASSERT(splsoftcamnet, SOFT) /* XXX no corresponding spl for alpha */ -GENSPLASSERT(splsoftclock, SOFT) -GENSPLASSERT(splsofttty, SOFT) /* XXX no corresponding spl for alpha */ -GENSPLASSERT(splsoftvm, SOFT) -GENSPLASSERT(splsofttq, SOFT) -GENSPLASSERT(splstatclock, CLOCK) -GENSPLASSERT(spltty, IO) -GENSPLASSERT(splvm, IO) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 1e37030..301e010 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -416,7 +416,7 @@ ia64_init() * Find the beginning and end of the kernel. */ kernstart = trunc_page(kernel_text); -#ifdef DDB +#ifdef DDBxx ksym_start = (void *)bootinfo.ssym; ksym_end = (void *)bootinfo.esym; kernend = (vm_offset_t)round_page(ksym_end); diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index ce673a1..c78b08a 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -99,8 +99,6 @@ globaldata_init(struct globaldata *globaldata, int cpuno, size_t sz) bzero(globaldata, sz); globaldata->gd_cpuno = cpuno; globaldata->gd_other_cpus = all_cpus & ~(1 << cpuno); - globaldata->gd_next_asn = 0; - globaldata->gd_current_asngen = 1; cpuno_to_globaldata[cpuno] = globaldata; } diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 588f32f..7953fbe 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -196,12 +196,19 @@ static boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ vm_offset_t kernel_vm_end; /* - * Data for the ASN allocator + * Values for ptc.e. XXX values for SKI. */ -static int pmap_maxasn; -static int pmap_nextasn = 0; -static u_int pmap_current_asngen = 1; -static pmap_t pmap_active = 0; +static u_int64_t pmap_pte_e_base = 0x100000000; +static u_int64_t pmap_pte_e_count1 = 3; +static u_int64_t pmap_pte_e_count2 = 2; +static u_int64_t pmap_pte_e_stride1 = 0x2000; +static u_int64_t pmap_pte_e_stride2 = 0x100000000; + +/* + * Data for the RID allocator + */ +static int pmap_nextrid; +static int pmap_ridbits = 18; /* * Data for the pv entry allocation mechanism @@ -219,11 +226,9 @@ static struct pv_entry *pvbootinit; static PMAP_INLINE void free_pv_entry __P((pv_entry_t pv)); static pv_entry_t get_pv_entry __P((void)); static void ia64_protection_init __P((void)); -static void pmap_changebit __P((vm_page_t m, int bit, boolean_t setem)); static void pmap_remove_all __P((vm_page_t m)); static void pmap_enter_quick __P((pmap_t pmap, vm_offset_t va, vm_page_t m)); -static boolean_t pmap_is_referenced __P((vm_page_t m)); vm_offset_t pmap_steal_memory(vm_size_t size) @@ -265,11 +270,11 @@ pmap_bootstrap() int boot_pvs; /* - * Setup ASNs + * Setup RIDs. We use the bits above pmap_ridbits for a + * generation counter, saving generation zero for + * 'invalid'. RIDs 0..7 are reserved for the kernel. */ - pmap_nextasn = 0; - pmap_maxasn = 0; - pmap_current_asngen = 1; + pmap_nextrid = (1 << pmap_ridbits) + 8; avail_start = phys_avail[0]; for (i = 0; phys_avail[i+2]; i+= 2) ; @@ -289,11 +294,9 @@ pmap_bootstrap() * the boot sequence (XXX and which no longer exists). */ kernel_pmap = &kernel_pmap_store; + kernel_pmap->pm_rid = 0; kernel_pmap->pm_count = 1; kernel_pmap->pm_active = 1; - kernel_pmap->pm_asn = 0; - kernel_pmap->pm_asngen = pmap_current_asngen; - pmap_nextasn = 1; TAILQ_INIT(&kernel_pmap->pm_pvlist); /* @@ -308,10 +311,8 @@ pmap_bootstrap() * handlers. Here we just make sure that they have the largest * possible page size to minimise TLB usage. */ -#if 1 ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2)); ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2)); -#endif /* * We need some PVs to cope with pmap_kenter() calls prior to @@ -398,83 +399,70 @@ pmap_init2() ***************************************************/ static void -pmap_invalidate_asn(pmap_t pmap) +pmap_invalidate_rid(pmap_t pmap) { - pmap->pm_asngen = 0; + KASSERT(pmap != kernel_pmap, + ("changing kernel_pmap's RID")); + KASSERT(pmap == PCPU_GET(current_pmap), + ("invalidating RID of non-current pmap")); + pmap_remove_pages(pmap, IA64_RR_BASE(0), IA64_RR_BASE(5)); + pmap->pm_rid = 0; } static void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { -#if 0 - if (pmap_isactive(pmap)) { - IA64_TBIS(va); - ia64_pal_imb(); /* XXX overkill? */ - } else - pmap_invalidate_asn(pmap); -#endif + KASSERT(pmap == PCPU_GET(current_pmap), + ("invalidating TLB for non-current pmap")); + ia64_ptc_l(va, PAGE_SHIFT << 2); } static void pmap_invalidate_all(pmap_t pmap) { -#if 0 - if (pmap_isactive(pmap)) { - IA64_TBIA(); - ia64_pal_imb(); /* XXX overkill? */ - } else - pmap_invalidate_asn(pmap); -#endif + u_int64_t addr; + int i, j; + u_int32_t psr; + + KASSERT(pmap == PCPU_GET(current_pmap), + ("invalidating TLB for non-current pmap")); + + psr = save_intr(); + disable_intr(); + addr = pmap_pte_e_base; + for (i = 0; i < pmap_pte_e_count1; i++) { + for (j = 0; j < pmap_pte_e_count2; j++) { + ia64_ptc_e(addr); + addr += pmap_pte_e_stride2; + } + addr += pmap_pte_e_stride1; + } + restore_intr(psr); } static void -pmap_get_asn(pmap_t pmap) +pmap_get_rid(pmap_t pmap) { + if ((pmap_nextrid & ((1 << pmap_ridbits) - 1)) == 0) { + /* + * Start a new ASN generation. + * + * Invalidate all per-process mappings and I-cache + */ + pmap_nextrid += 8; + + /* + * Since we are about to start re-using ASNs, we must + * clear out the TLB. + * with the ASN. + */ #if 0 - if (pmap->pm_asngen != pmap_current_asngen) { - if (pmap_nextasn > pmap_maxasn) { - /* - * Start a new ASN generation. - * - * Invalidate all per-process mappings and I-cache - */ - pmap_nextasn = 0; - pmap_current_asngen++; - - if (pmap_current_asngen == 0) { - /* - * Clear the pm_asngen of all pmaps. - * This is safe since it is only called from - * pmap_activate after it has deactivated - * the old pmap. - */ - struct proc *p; - pmap_t tpmap; - -#ifdef PMAP_DIAGNOSTIC - printf("pmap_get_asn: generation rollover\n"); + IA64_TBIAP(); + ia64_pal_imb(); /* XXX overkill? */ #endif - pmap_current_asngen = 1; - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_vmspace) { - tpmap = vmspace_pmap(p->p_vmspace); - tpmap->pm_asngen = 0; - } - } - } - - /* - * Since we are about to start re-using ASNs, we must - * clear out the TLB and the I-cache since they are tagged - * with the ASN. - */ - IA64_TBIAP(); - ia64_pal_imb(); /* XXX overkill? */ - } - pmap->pm_asn = pmap_nextasn++; - pmap->pm_asngen = pmap_current_asngen; } -#endif + pmap->pm_rid = pmap_nextrid; + pmap_nextrid += 8; } /*************************************************** @@ -682,11 +670,10 @@ pmap_pinit0(pmap) */ pmap_pinit(pmap); pmap->pm_flags = 0; + pmap->pm_rid = 0; pmap->pm_count = 1; pmap->pm_ptphint = NULL; pmap->pm_active = 0; - pmap->pm_asn = 0; - pmap->pm_asngen = 0; TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); } @@ -700,11 +687,10 @@ pmap_pinit(pmap) register struct pmap *pmap; { pmap->pm_flags = 0; + pmap->pm_rid = 0; pmap->pm_count = 1; pmap->pm_ptphint = NULL; pmap->pm_active = 0; - pmap->pm_asn = 0; - pmap->pm_asngen = 0; TAILQ_INIT(&pmap->pm_pvlist); bzero(&pmap->pm_stats, sizeof pmap->pm_stats); } @@ -1140,6 +1126,7 @@ pmap_kenter(vm_offset_t va, vm_offset_t pa) pv = pmap_make_pv(kernel_pmap, va); pmap_set_pv(kernel_pmap, pv, pa, (PTE_AR_RWX<<2) | PTE_PL_KERN, 0); + pmap_invalidate_page(kernel_pmap, va); } /* @@ -1151,8 +1138,10 @@ pmap_kremove(vm_offset_t va) pv_entry_t pv; pv = pmap_find_pv(kernel_pmap, va); - if (pv) + if (pv) { pmap_remove_pv(kernel_pmap, pv, 0); + pmap_invalidate_page(kernel_pmap, va); + } } /* @@ -1225,6 +1214,7 @@ pmap_remove_page(pmap_t pmap, vm_offset_t va) if (pv) { m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte)); rtval = pmap_remove_pv(pmap, pv, m); + pmap_invalidate_page(pmap, va); } splx(s); @@ -1274,7 +1264,9 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) pvnext = TAILQ_NEXT(pv, pv_plist); if (pv->pv_va >= sva && pv->pv_va < eva) { vm_page_t m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte)); + va = pv->pv_va; pmap_remove_pv(pmap, pv, m); + pmap_invalidate_page(pmap, va); } } splx(s); @@ -1316,8 +1308,9 @@ pmap_remove_all(vm_page_t m) while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { vm_page_t m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte)); + vm_offset_t va = pv->pv_va; pmap_remove_pv(pv->pv_pmap, pv, m); - pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_invalidate_page(pv->pv_pmap, va); } vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE); @@ -1333,19 +1326,25 @@ pmap_remove_all(vm_page_t m) void pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) { + pmap_t oldpmap; pv_entry_t pv; int newprot; if (pmap == NULL) return; + oldpmap = pmap_install(pmap); + if ((prot & VM_PROT_READ) == VM_PROT_NONE) { pmap_remove(pmap, sva, eva); + pmap_install(oldpmap); return; } - if (prot & VM_PROT_WRITE) + if (prot & VM_PROT_WRITE) { + pmap_install(oldpmap); return; + } newprot = pte_prot(pmap, prot); @@ -1370,6 +1369,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) sva += PAGE_SIZE; } + pmap_install(oldpmap); } /* @@ -1388,6 +1388,7 @@ void pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, boolean_t wired) { + pmap_t oldpmap; vm_offset_t pa; pv_entry_t pv; vm_offset_t opa; @@ -1397,6 +1398,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, if (pmap == NULL) return; + oldpmap = pmap_install(pmap); + va &= ~PAGE_MASK; #ifdef PMAP_DIAGNOSTIC if (va > VM_MAX_KERNEL_ADDRESS) @@ -1465,6 +1468,8 @@ validate: if (origpte.pte_p) pmap_invalidate_page(pmap, va); } + + pmap_install(oldpmap); } /* @@ -1523,6 +1528,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, vm_pindex_t pindex, vm_size_t size, int limit) { + pmap_t oldpmap; vm_offset_t tmpidx; int psize; vm_page_t p; @@ -1531,11 +1537,14 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, if (pmap == NULL || object == NULL) return; + oldpmap = pmap_install(pmap); + psize = ia64_btop(size); if ((object->type != OBJT_VNODE) || (limit && (psize > MAX_INIT_PT) && (object->resident_page_count > MAX_INIT_PT))) { + pmap_install(oldpmap); return; } @@ -1592,6 +1601,7 @@ pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, } } } + pmap_install(oldpmap); return; } @@ -1697,11 +1707,14 @@ pmap_change_wiring(pmap, va, wired) vm_offset_t va; boolean_t wired; { + pmap_t oldpmap; pv_entry_t pv; if (pmap == NULL) return; + oldpmap = pmap_install(pmap); + pv = pmap_find_pv(pmap, va); if (wired && !pmap_pte_w(&pv->pv_pte)) @@ -1714,6 +1727,8 @@ pmap_change_wiring(pmap, va, wired) * invalidate TLB. */ pmap_pte_set_w(&pv->pv_pte, wired); + + pmap_install(oldpmap); } @@ -1895,66 +1910,6 @@ pmap_remove_pages(pmap, sva, eva) } /* - * this routine is used to modify bits in ptes - */ -static void -pmap_changebit(vm_page_t m, int bit, boolean_t setem) -{ -#if 0 - pv_entry_t pv; - int changed; - int s; - - if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) - return; - - s = splvm(); - changed = 0; - - /* - * Loop over all current mappings setting/clearing as appropos If - * setting RO do we need to clear the VAC? - */ - for (pv = TAILQ_FIRST(&m->md.pv_list); - pv; - pv = TAILQ_NEXT(pv, pv_list)) { - - /* - * don't write protect pager mappings - */ - if (!setem && bit == (PG_UWE|PG_KWE)) { - if (!pmap_track_modified(pv->pv_va)) - continue; - } - -#if defined(PMAP_DIAGNOSTIC) - if (!pv->pv_pmap) { - printf("Null pmap (cb) at va: 0x%lx\n", pv->pv_va); - continue; - } -#endif - - pte = pmap_lev3pte(pv->pv_pmap, pv->pv_va); - - changed = 0; - if (setem) { - *pte |= bit; - changed = 1; - } else { - pt_entry_t pbits = *pte; - if (pbits & bit) { - changed = 1; - *pte = pbits & ~bit; - } - } - if (changed) - pmap_invalidate_page(pv->pv_pmap, pv->pv_va); - } - splx(s); -#endif -} - -/* * pmap_page_protect: * * Lower the permission for all mappings to a given page. @@ -1962,15 +1917,24 @@ pmap_changebit(vm_page_t m, int bit, boolean_t setem) void pmap_page_protect(vm_page_t m, vm_prot_t prot) { -#if 0 - if ((prot & VM_PROT_WRITE) == 0) { - if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { - pmap_changebit(m, PG_KWE|PG_UWE, FALSE); - } else { - pmap_remove_all(m); + pv_entry_t pv; + + if ((prot & VM_PROT_WRITE) != 0) + return; + if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) { + for (pv = TAILQ_FIRST(&m->md.pv_list); + pv; + pv = TAILQ_NEXT(pv, pv_list)) { + int newprot = pte_prot(pv->pv_pmap, prot); + pmap_t oldpmap = pmap_install(pv->pv_pmap); + pmap_pte_set_prot(&pv->pv_pte, newprot); + pmap_update_vhpt(pv); + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_install(oldpmap); } + } else { + pmap_remove_all(m); } -#endif } vm_offset_t @@ -1999,15 +1963,19 @@ pmap_ts_referenced(vm_page_t m) pv; pv = TAILQ_NEXT(pv, pv_list)) { if (pv->pv_pte.pte_a) { + pmap_t oldpmap = pmap_install(pv->pv_pmap); count++; pv->pv_pte.pte_a = 0; pmap_update_vhpt(pv); + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_install(oldpmap); } } return count; } +#if 0 /* * pmap_is_referenced: * @@ -2032,6 +2000,7 @@ pmap_is_referenced(vm_page_t m) return 0; } +#endif /* * pmap_is_modified: @@ -2073,8 +2042,11 @@ pmap_clear_modify(vm_page_t m) pv; pv = TAILQ_NEXT(pv, pv_list)) { if (pv->pv_pte.pte_d) { + pmap_t oldpmap = pmap_install(pv->pv_pmap); pv->pv_pte.pte_d = 0; pmap_update_vhpt(pv); + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_install(oldpmap); } } } @@ -2096,8 +2068,11 @@ pmap_clear_reference(vm_page_t m) pv; pv = TAILQ_NEXT(pv, pv_list)) { if (pv->pv_pte.pte_a) { + pmap_t oldpmap = pmap_install(pv->pv_pmap); pv->pv_pte.pte_a = 0; pmap_update_vhpt(pv); + pmap_invalidate_page(pv->pv_pmap, pv->pv_va); + pmap_install(oldpmap); } } } @@ -2233,39 +2208,59 @@ pmap_mincore(pmap, addr) void pmap_activate(struct proc *p) { - pmap_t pmap; + pmap_install(vmspace_pmap(p->p_vmspace)); +} - pmap = vmspace_pmap(p->p_vmspace); +pmap_t +pmap_install(pmap_t pmap) +{ + pmap_t oldpmap; + int rid; - if (pmap_active && pmap != pmap_active) { - pmap_active->pm_active = 0; - pmap_active = 0; - } + oldpmap = PCPU_GET(current_pmap); - if (pmap->pm_asngen != pmap_current_asngen) - pmap_get_asn(pmap); + if (pmap == oldpmap || pmap == kernel_pmap) + return pmap; + + PCPU_SET(current_pmap, pmap); + if (!pmap) { + /* + * RIDs 0..4 have no mappings to make sure we generate + * page faults on accesses. + */ + ia64_set_rr(IA64_RR_BASE(0), (0 << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(1), (1 << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(2), (2 << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(3), (3 << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(4), (4 << 8)|(PAGE_SHIFT << 2)|1); + return oldpmap; + } - pmap_active = pmap; pmap->pm_active = 1; /* XXX use bitmap for SMP */ -#if 0 - p->p_addr->u_pcb.pcb_hw.apcb_asn = pmap->pm_asn; -#endif + reinstall: + rid = pmap->pm_rid & ((1 << pmap_ridbits) - 1); + ia64_set_rr(IA64_RR_BASE(0), ((rid + 0) << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(1), ((rid + 1) << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(2), ((rid + 2) << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(3), ((rid + 3) << 8)|(PAGE_SHIFT << 2)|1); + ia64_set_rr(IA64_RR_BASE(4), ((rid + 4) << 8)|(PAGE_SHIFT << 2)|1); - if (p == curproc) { -#if 0 - ia64_pal_swpctx((u_long)p->p_md.md_pcbpaddr); -#endif + /* + * If we need a new RID, get it now. Note that we need to + * remove our old mappings (if any) from the VHTP, so we will + * run on the old RID for a moment while we invalidate the old + * one. XXX maybe we should just clear out the VHTP when the + * RID generation rolls over. + */ + if ((pmap->pm_rid>>pmap_ridbits) != (pmap_nextrid>>pmap_ridbits)) { + if (pmap->pm_rid) + pmap_invalidate_rid(pmap); + pmap_get_rid(pmap); + goto reinstall; } -} -void -pmap_deactivate(struct proc *p) -{ - pmap_t pmap; - pmap = vmspace_pmap(p->p_vmspace); - pmap->pm_active = 0; - pmap_active = 0; + return oldpmap; } vm_offset_t diff --git a/sys/ia64/ia64/swtch.s b/sys/ia64/ia64/swtch.s index 7e29e62..e2aa9d2 100644 --- a/sys/ia64/ia64/swtch.s +++ b/sys/ia64/ia64/swtch.s @@ -104,6 +104,7 @@ ENTRY(savectx, 1) */ ENTRY(restorectx, 1) + add r3=U_PCB_UNAT,in0 // point at NaT for r4..r7 mov ar.rsc=0 ;; // switch off the RSE ld8 r16=[r3] // load NaT for r4..r7 @@ -155,6 +156,130 @@ ENTRY(restorectx, 1) br.ret.sptk.few rp END(restorectx) +ENTRY(cpu_switch, 0) + + add r16=GD_CURPROC,r13 ;; + ld8 r17=[r16] ;; + add r17=P_ADDR,r17 ;; + + flushrs // push out caller's dirty regs + mov r3=ar.unat // caller's value for ar.unat + ;; + mov ar.rsc=0 // stop the RSE after the flush + ;; + mov r16=ar.rnat // read RSE's NaT collection + mov r18=ar.bspstore + mov r19=b0 + mov r20=b1 + mov r21=b2 + mov r22=b3 + mov r23=b4 + mov r24=b5 + ;; + st8.spill [r17]=r4,8 ;; // save r4..r6 + st8.spill [r17]=r5,8 ;; // and accumulate NaT bits + st8.spill [r17]=r6,8 ;; + st8.spill [r17]=r7,8 ;; + + stf.spill [r17]=f2,16 ;; // save f2..f5 with NaTVals + stf.spill [r17]=f3,16 ;; + stf.spill [r17]=f4,16 ;; + stf.spill [r17]=f5,16 ;; + + st8 [r17]=r19,8 ;; // save b0..b5 + st8 [r17]=r20,8 ;; + st8 [r17]=r21,8 ;; + st8 [r17]=r22,8 ;; + st8 [r17]=r23,8 ;; + st8 [r17]=r24,8 ;; + + mov r19=ar.unat // NaT bits for r4..r6 + mov r20=pr + mov ret0=r0 // return zero + + st8 [r17]=r3,8 ;; // save caller's ar.unat + st8 [r17]=sp,8 ;; // stack pointer + st8 [r17]=r2,8 ;; // ar.pfs + st8 [r17]=r18,8 ;; // ar.bspstore + st8 [r17]=r19,8 ;; // our NaT bits + st8 [r17]=r16,8 ;; // ar.rnat + st8 [r17]=r20,8 ;; // pr + + addl r15=@ltoff(sched_lock),gp ;; + ld8 r15=[r15] ;; + add r15=MTX_RECURSE,r15 ;; + ld4 r15=[r15] ;; + st8 [r17]=r15 ;; // save sched_lock.mtx_recurse + + mov ar.rsc=3 // turn RSE back on + + br.call.sptk.few rp=chooseproc + add r14=GD_CURPROC,r13 ;; + ld8 r14=[r14] ;; + cmp.eq p6,p0=r14,ret0 // chooseproc() == curproc ? +(p6) br.dpnt.few 9f // don't bother to restore + + add r15=P_ADDR,ret0 ;; + ld8 r15=[r15] ;; + + add r3=U_PCB_UNAT,r15 // point at NaT for r4..r7 + mov ar.rsc=0 ;; // switch off the RSE + ld8 r16=[r3] // load NaT for r4..r7 + ;; + mov ar.unat=r16 + ;; + ld8.fill r4=[r15],8 ;; // restore r4 + ld8.fill r5=[r15],8 ;; // restore r5 + ld8.fill r6=[r15],8 ;; // restore r6 + ld8.fill r7=[r15],8 ;; // restore r7 + + ldf.fill f2=[r15],16 ;; // restore f2 + ldf.fill f3=[r15],16 ;; // restore f3 + ldf.fill f4=[r15],16 ;; // restore f4 + ldf.fill f5=[r15],16 ;; // restore f5 + + ld8 r16=[r15],8 ;; // restore b0 + ld8 r17=[r15],8 ;; // restore b1 + ld8 r18=[r15],8 ;; // restore b2 + ld8 r19=[r15],8 ;; // restore b3 + ld8 r20=[r15],8 ;; // restore b4 + ld8 r21=[r15],8 ;; // restore b5 + + mov b0=r16 + mov b1=r17 + mov b2=r18 + mov b3=r19 + mov b4=r20 + mov b5=r21 + + ld8 r16=[r15],8 ;; // caller's ar.unat + ld8 sp=[r15],8 ;; // stack pointer + ld8 r17=[r15],8 ;; // ar.pfs + ld8 r18=[r15],16 ;; // ar.bspstore, skip ar.unat + ld8 r19=[r15],8 ;; // ar.rnat + ld8 r20=[r15],8 ;; // pr + + mov ar.unat=r16 + mov ar.pfs=r17 + mov ar.bspstore=r18 ;; + mov ar.rnat=r19 + mov pr=r20,0x1ffff + ;; + loadrs + mov ar.rsc=3 // restart RSE + invala + ;; + ld8 r14=[r15] // restore sched_lock.mtx_recurse + addl r16=@ltoff(sched_lock),gp ;; + ld8 r15=[r16] ;; + add r15=MTX_RECURSE,r15 ;; + st4 [r15]=r14 + +9: + br.ret.sptk.few rp + +END(cpu_switch) + /* * switch_trampoline() * @@ -167,12 +292,6 @@ ENTRY(restorectx, 1) ENTRY(switch_trampoline, 0) MTX_EXIT(sched_lock, r14, r15) - // Clear sched_lock.mtx_recurse (normally restored in cpu_switch). - addl r15=@ltoff(sched_lock),gp ;; - ld8 r15=[r15] ;; - add r15=MTX_RECURSE,r15 ;; - st4 [r15]=r0 - alloc r14=ar.pfs,0,0,1,0 mov b7=r4 mov b0=r5 diff --git a/sys/ia64/ia64/synch_machdep.c b/sys/ia64/ia64/synch_machdep.c index 7208921..33a586a 100644 --- a/sys/ia64/ia64/synch_machdep.c +++ b/sys/ia64/ia64/synch_machdep.c @@ -547,20 +547,3 @@ mtx_destroy(struct mtx *m) mtx_cur_cnt--; mtx_exit(&all_mtx, MTX_DEF); } - -void -cpu_switch() -{ - struct proc *p = curproc; - - if (savectx(&p->p_addr->u_pcb)) { - sched_lock.mtx_lock = CURTHD; - sched_lock.mtx_recurse = p->p_addr->u_pcb.pcb_schednest; - return; - } - - p = chooseproc(); - curproc = p; - ia64_set_k7((u_int64_t) curproc); - restorectx(&p->p_addr->u_pcb); -} diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c index 5c2c2e4..b73e8bb 100644 --- a/sys/ia64/ia64/vm_machdep.c +++ b/sys/ia64/ia64/vm_machdep.c @@ -268,6 +268,13 @@ cpu_fork(p1, p2, flags) up->u_pcb.pcb_r5 = FDESC_FUNC(exception_return); up->u_pcb.pcb_r6 = (u_int64_t)p2; up->u_pcb.pcb_b0 = FDESC_FUNC(switch_trampoline); + + /* + * Clear the saved recursion count for sched_lock + * since the child needs only one count which is + * released in switch_trampoline. + */ + up->u_pcb.pcb_schednest = 0; } } diff --git a/sys/ia64/include/atomic.h b/sys/ia64/include/atomic.h index a7b3e21..d4d2bbc 100644 --- a/sys/ia64/include/atomic.h +++ b/sys/ia64/include/atomic.h @@ -187,4 +187,27 @@ atomic_cmpset_ptr(volatile void *dst, void *exp, void *src) (u_long)exp, (u_long)src); } +static __inline u_int32_t +atomic_readandclear_32(volatile u_int32_t* p) +{ + u_int32_t val; + do { + val = *p; + } while (!atomic_cmpset_32(p, val, 0)); + return val; +} + +static __inline u_int64_t +atomic_readandclear_64(volatile u_int64_t* p) +{ + u_int64_t val; + do { + val = *p; + } while (!atomic_cmpset_64(p, val, 0)); + return val; +} + +#define atomic_readandclear_int atomic_readandclear_32 +#define atomic_readandclear_long atomic_readandclear_64 + #endif /* ! _MACHINE_ATOMIC_H_ */ diff --git a/sys/ia64/include/cpu.h b/sys/ia64/include/cpu.h index 3da3331..79f3727 100644 --- a/sys/ia64/include/cpu.h +++ b/sys/ia64/include/cpu.h @@ -65,7 +65,7 @@ struct clockframe { #define CLKF_BASEPRI(framep) \ (((framep)->cf_tf.tf_cr_ipsr & IA64_PSR_I) == 0) #define CLKF_PC(framep) ((framep)->cf_tf.tf_cr_iip) -#define CLKF_INTR(framep) (intr_nesting_level >= 2) +#define CLKF_INTR(framep) (PCPU_GET(intr_nesting_level) >= 2) /* * Preempt the current process if in interrupt from user mode, @@ -92,7 +92,6 @@ struct clockframe { #define aston() PCPU_SET(astpending, 1) #ifdef _KERNEL -extern u_int32_t intr_nesting_level; /* bookeeping only; counts sw intrs */ extern u_int32_t want_resched; /* resched() was called */ #endif diff --git a/sys/ia64/include/db_machdep.h b/sys/ia64/include/db_machdep.h index 1517a54..b807b37 100644 --- a/sys/ia64/include/db_machdep.h +++ b/sys/ia64/include/db_machdep.h @@ -43,24 +43,35 @@ typedef vm_offset_t db_addr_t; /* address - unsigned */ typedef long db_expr_t; /* expression - signed */ - typedef struct trapframe db_regs_t; db_regs_t ddb_regs; /* register state */ #define DDB_REGS (&ddb_regs) -#define PC_REGS(regs) ((db_addr_t)(regs)->tf_regs[FRAME_PC]) +#define PC_REGS(regs) ((db_addr_t)(regs)->tf_cr_iip \ + + (((regs)->tf_cr_ipsr >> 41) & 3)) #define BKPT_INST 0x00000080 /* breakpoint instruction */ #define BKPT_SIZE (4) /* size of breakpoint inst */ #define BKPT_SET(inst) (BKPT_INST) -#define FIXUP_PC_AFTER_BREAK \ - (ddb_regs.tf_regs[FRAME_PC] -= BKPT_SIZE); +#define FIXUP_PC_AFTER_BREAK + +#define db_clear_single_step(regs) 0 +#define db_set_single_step(regs) 0 -#define IS_BREAKPOINT_TRAP(type, code) ((type) == ALPHA_KENTRY_IF && \ - (code) == ALPHA_IF_CODE_BPT) +#define IS_BREAKPOINT_TRAP(type, code) 0 #define IS_WATCHPOINT_TRAP(type, code) 0 +#define inst_trap_return(ins) 0 +#define inst_return(ins) 0 +#define inst_call(ins) 0 +#define inst_branch(ins) 0 +#define inst_load(ins) 0 +#define inst_store(ins) 0 +#define inst_unconditional_flow_transfer(ins) 0 + +#define branch_taken(ins, pc, regs) pc + /* * Functions needed for software single-stepping. */ @@ -68,9 +79,8 @@ db_regs_t ddb_regs; /* register state */ /* No delay slots on Alpha. */ #define next_instr_address(v, b) ((db_addr_t) ((b) ? (v) : ((v) + 4))) -u_long db_register_value __P((db_regs_t *, int)); -int kdb_trap __P((unsigned long, unsigned long, unsigned long, - unsigned long, struct trapframe *)); +u_long db_register_value(db_regs_t *, int); +int kdb_trap(int vector, struct trapframe *regs); /* * Pretty arbitrary diff --git a/sys/ia64/include/globaldata.h b/sys/ia64/include/globaldata.h index 87c9fe5..eb88422 100644 --- a/sys/ia64/include/globaldata.h +++ b/sys/ia64/include/globaldata.h @@ -54,6 +54,7 @@ struct globaldata { int gd_inside_intr; u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */ u_int64_t gd_pending_ipis; /* pending IPI events */ + struct pmap *gd_current_pmap; /* which pmap is active */ u_int32_t gd_next_asn; /* next ASN to allocate */ u_int32_t gd_current_asngen; /* ASN rollover check */ u_int32_t gd_intr_nesting_level; /* interrupt recursion */ diff --git a/sys/ia64/include/ia64_cpu.h b/sys/ia64/include/ia64_cpu.h index 1639e88..186e136 100644 --- a/sys/ia64/include/ia64_cpu.h +++ b/sys/ia64/include/ia64_cpu.h @@ -183,6 +183,42 @@ ia64_tpa(u_int64_t va) } /* + * Generate a ptc.e instruction. + */ +static __inline void +ia64_ptc_e(u_int64_t v) +{ + __asm __volatile("ptc.e %0;;" :: "r"(v)); +} + +/* + * Generate a ptc.g instruction. + */ +static __inline void +ia64_ptc_g(u_int64_t va, u_int64_t log2size) +{ + __asm __volatile("ptc.g %0,%1;;" :: "r"(va), "r"(log2size)); +} + +/* + * Generate a ptc.ga instruction. + */ +static __inline void +ia64_ptc_ga(u_int64_t va, u_int64_t log2size) +{ + __asm __volatile("ptc.ga %0,%1;;" :: "r"(va), "r"(log2size)); +} + +/* + * Generate a ptc.l instruction. + */ +static __inline void +ia64_ptc_l(u_int64_t va, u_int64_t log2size) +{ + __asm __volatile("ptc.l %0,%1;;" :: "r"(va), "r"(log2size)); +} + +/* * Read the value of ar.k0. */ static __inline u_int64_t diff --git a/sys/ia64/include/inst.h b/sys/ia64/include/inst.h new file mode 100644 index 0000000..5abea43 --- /dev/null +++ b/sys/ia64/include/inst.h @@ -0,0 +1,1168 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * 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 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 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. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_INST_H_ +#define _MACHINE_INST_H_ + +union ia64_instruction { + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + + u_int64_t x4 :4; + u_int64_t v :1; + u_int64_t x2a :2; + u_int64_t resv :1; + u_int64_t op :4; + } A1; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t ct2d :2; + u_int64_t x4 :4; + u_int64_t v :1; + u_int64_t x2a :2; + u_int64_t resv :1; + u_int64_t op :4; + } A2; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t x2b :2; + u_int64_t x4 :4; + u_int64_t v :1; + u_int64_t x2a :2; + u_int64_t s :1; + u_int64_t op :4; + } A3; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t imm6d :6; + u_int64_t v :1; + u_int64_t x2a :2; + u_int64_t s :1; + u_int64_t op :4; + } A4; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t r3 :2; + u_int64_t imm5c :5; + u_int64_t imm9d :9; + u_int64_t s :1; + u_int64_t op :4; + } A5; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t c :1; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t p2 :6; + u_int64_t ta :1; + u_int64_t x2 :2; + u_int64_t tb :1; + u_int64_t op :4; + } A6; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t c :1; + u_int64_t zero :7; + u_int64_t r3 :7; + u_int64_t p2 :6; + u_int64_t ta :1; + u_int64_t x2 :2; + u_int64_t tb :1; + u_int64_t op :4; + } A7; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t c :1; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t p2 :6; + u_int64_t ta :1; + u_int64_t x2 :2; + u_int64_t s :1; + u_int64_t op :4; + } A8; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x2b :2; + u_int64_t x4 :4; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } A9; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t ct2d :2; + u_int64_t x4 :4; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } A10; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t resv :1; + u_int64_t x2b :2; + u_int64_t ct2d :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I1; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t resv :1; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I2; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t mbt4c :4; + u_int64_t resv :4; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I3; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t mht8c :8; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I4; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t resv :1; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I5; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv1 :1; + u_int64_t count5b :5; + u_int64_t resv2 :1; + u_int64_t r3 :7; + u_int64_t resv3 :1; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I6; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t resv :1; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I7; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t count5c :5; + u_int64_t resv :2; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I8; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t zero :7; + u_int64_t r3 :7; + u_int64_t resv :1; + u_int64_t x2b :2; + u_int64_t x2c :2; + u_int64_t ve :1; + u_int64_t zb :1; + u_int64_t x2a :2; + u_int64_t za :1; + u_int64_t op :4; + } I9; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t count6d :6; + u_int64_t x :1; + u_int64_t x2 :2; + u_int64_t resv :1; + u_int64_t op :4; + } I10; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t y :1; + u_int64_t pos6b :6; + u_int64_t r3 :7; + u_int64_t len6d :6; + u_int64_t x :1; + u_int64_t x2 :2; + u_int64_t resv :1; + u_int64_t op :4; + } I11; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t cpos6c :6; + u_int64_t y :1; + u_int64_t len6d :6; + u_int64_t x :1; + u_int64_t x2 :2; + u_int64_t resv :1; + u_int64_t op :4; + } I12; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t cpos6c :6; + u_int64_t y :1; + u_int64_t len6d :6; + u_int64_t x :1; + u_int64_t x2 :2; + u_int64_t s :1; + u_int64_t op :4; + } I13; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv :1; + u_int64_t cpos6b :6; + u_int64_t r3 :7; + u_int64_t len6d :6; + u_int64_t x :1; + u_int64_t x2 :2; + u_int64_t s :1; + u_int64_t op :4; + } I14; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t len4d :6; + u_int64_t cpos6d :6; + u_int64_t op :4; + } I15; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t c :1; + u_int64_t y :1; + u_int64_t pos6b :6; + u_int64_t r3 :7; + u_int64_t p2 :6; + u_int64_t ta :1; + u_int64_t x2 :2; + u_int64_t tb :1; + u_int64_t op :4; + } I16; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t c :1; + u_int64_t y :1; + u_int64_t resv :6; + u_int64_t r3 :7; + u_int64_t p2 :6; + u_int64_t ta :1; + u_int64_t x2 :2; + u_int64_t tb :1; + u_int64_t op :4; + } I17; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv :1; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t i :1; + u_int64_t op :4; + } I19; + struct { + u_int64_t qp :6; + u_int64_t imm7a :7; + u_int64_t r2 :7; + u_int64_t imm13c :13; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } I20; + struct { + u_int64_t qp :6; + u_int64_t b1 :3; + u_int64_t resv1 :4; + u_int64_t r2 :7; + u_int64_t wh :2; + u_int64_t x :1; + u_int64_t ih :1; + u_int64_t timm9c :9; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I21; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t b2 :3; + u_int64_t resv1 :11; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I22; + struct { + u_int64_t qp :6; + u_int64_t mask7a :7; + u_int64_t r2 :7; + u_int64_t resv1 :4; + u_int64_t mask8c :8; + u_int64_t resv2 :1; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } I23; + struct { + u_int64_t qp :6; + u_int64_t imm27a :27; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } I24; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv1 :14; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I25; + struct { + u_int64_t qp :6; + u_int64_t resv1 :7; + u_int64_t r2 :7; + u_int64_t ar3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I26; + struct { + u_int64_t qp :6; + u_int64_t resv1 :7; + u_int64_t imm7b :7; + u_int64_t ar3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } I27; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv1 :7; + u_int64_t ar3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I28; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv1 :7; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv2 :1; + u_int64_t op :4; + } I29; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv7 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M1; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M2, M16; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t i :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t s :1; + u_int64_t op :4; + } M3; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M4; + struct { + u_int64_t qp :6; + u_int64_t imm7a :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t i :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t s :1; + u_int64_t op :4; + } M5; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t resv7 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M6; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M7; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t i :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t s :1; + u_int64_t op :4; + } M8; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t f2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M9; + struct { + u_int64_t qp :6; + u_int64_t imm7a :7; + u_int64_t f2 :7; + u_int64_t r3 :7; + u_int64_t i :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t s :1; + u_int64_t op :4; + } M10; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M11, M12; + struct { + u_int64_t qp :6; + u_int64_t resv14 :14; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M13; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M14; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t imm7b :7; + u_int64_t r3 :7; + u_int64_t i :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t s :1; + u_int64_t op :4; + } M15; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t i2b :2; + u_int64_t s :1; + u_int64_t resv4 :4; + u_int64_t r3 :7; + u_int64_t x :1; + u_int64_t hint :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M17; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t r2 :7; + u_int64_t resv7 :7; + u_int64_t x :1; + u_int64_t resv2 :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M18; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t f2 :7; + u_int64_t resv7 :7; + u_int64_t x :1; + u_int64_t resv2 :2; + u_int64_t x6 :6; + u_int64_t m :1; + u_int64_t op :4; + } M19; + struct { + u_int64_t qp :6; + u_int64_t imm7a :7; + u_int64_t r2 :7; + u_int64_t imm13c :13; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } M20; + struct { + u_int64_t qp :6; + u_int64_t imm7a :7; + u_int64_t f2 :7; + u_int64_t imm13c :13; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } M21; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm20b :20; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } M22; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t imm20b :20; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } M23; + struct { + u_int64_t qp :6; + u_int64_t resv21 :21; + u_int64_t x4 :4; + u_int64_t x2 :2; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M24, M25; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv14 :14; + u_int64_t x4 :4; + u_int64_t x2 :2; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M26; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t resv14 :14; + u_int64_t x4 :4; + u_int64_t x2 :2; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M27; + struct { + u_int64_t qp :6; + u_int64_t resv14 :14; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M28; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t r2 :7; + u_int64_t ar3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M29; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t imm7b :7; + u_int64_t ar3 :7; + u_int64_t x4 :4; + u_int64_t x2 :2; + u_int64_t x3 :3; + u_int64_t s :1; + u_int64_t op :4; + } M30; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv7 :7; + u_int64_t ar3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M31; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t r2 :7; + u_int64_t cr3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M32; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv7 :7; + u_int64_t cr3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M33; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t sof :7; + u_int64_t sol :7; + u_int64_t sor :4; + u_int64_t resv2 :2; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M34; + struct { + u_int64_t qp :6; + u_int64_t resv7a :7; + u_int64_t r2 :7; + u_int64_t resv7b :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M35; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv14 :14; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M36; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv1 :1; + u_int64_t x4 :4; + u_int64_t x2 :2; + u_int64_t x3 :3; + u_int64_t i :1; + u_int64_t op :4; + } M37; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M38; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t i2b :2; + u_int64_t resv5 :5; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M39; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t i2b :2; + u_int64_t resv5 :5; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M40; + struct { + u_int64_t qp :6; + u_int64_t resv7a :7; + u_int64_t r2 :7; + u_int64_t resv7b :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M41; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t r2 :7; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M42, M45; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t resv7 :7; + u_int64_t r3 :7; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t resv1 :1; + u_int64_t op :4; + } M43, M46; + struct { + u_int64_t qp :6; + u_int64_t imm21a :21; + u_int64_t x4 :4; + u_int64_t i2d :2; + u_int64_t x3 :3; + u_int64_t i :1; + u_int64_t op :4; + } M44; + struct { + u_int64_t qp :6; + u_int64_t btype :3; + u_int64_t resv3 :3; + u_int64_t p :1; + u_int64_t imm20b :20; + u_int64_t wh :2; + u_int64_t d :1; + u_int64_t s :1; + u_int64_t op :4; + } B1, B2; + struct { + u_int64_t qp :6; + u_int64_t b1 :3; + u_int64_t resv3 :3; + u_int64_t p :1; + u_int64_t imm20b :20; + u_int64_t wh :2; + u_int64_t d :1; + u_int64_t s :1; + u_int64_t op :4; + } B3; + struct { + u_int64_t qp :6; + u_int64_t btype :3; + u_int64_t resv3 :3; + u_int64_t p :1; + u_int64_t b2 :3; + u_int64_t resv11 :11; + u_int64_t x6 :6; + u_int64_t wh :2; + u_int64_t d :1; + u_int64_t s :1; + u_int64_t op :4; + } B4; + struct { + u_int64_t qp :6; + u_int64_t b1 :3; + u_int64_t resv3 :3; + u_int64_t p :1; + u_int64_t b2 :3; + u_int64_t resv17 :17; + u_int64_t wh :2; + u_int64_t d :1; + u_int64_t resv1 :1; + u_int64_t op :4; + } B5; + struct { + u_int64_t qp :6; + u_int64_t wh :3; + u_int64_t resv1 :1; + u_int64_t timm7a :7; + u_int64_t imm20b :20; + u_int64_t t2e :2; + u_int64_t ih :1; + u_int64_t s :1; + u_int64_t op :4; + } B6; + struct { + u_int64_t qp :6; + u_int64_t wh :3; + u_int64_t resv1a :1; + u_int64_t timm7a :7; + u_int64_t b2 :3; + u_int64_t resv11 :11; + u_int64_t x6 :6; + u_int64_t t2e :2; + u_int64_t ih :1; + u_int64_t resv1b :1; + u_int64_t op :4; + } B7; + struct { + u_int64_t zero :6; + u_int64_t resv21 :21; + u_int64_t x6 :6; + u_int64_t resv4 :4; + u_int64_t op :4; + } B8; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv1 :1; + u_int64_t x6 :6; + u_int64_t resv3 :3; + u_int64_t i :1; + u_int64_t op :4; + } B9; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t f4 :7; + u_int64_t sf :2; + u_int64_t x :1; + u_int64_t op :4; + } F1; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t f4 :7; + u_int64_t x2 :2; + u_int64_t x :1; + u_int64_t op :4; + } F2; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t f4 :7; + u_int64_t resv2 :2; + u_int64_t x :1; + u_int64_t op :4; + } F3; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t ta :1; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t p2 :6; + u_int64_t ra :1; + u_int64_t sf :2; + u_int64_t rb :1; + u_int64_t op :4; + } F4; + struct { + u_int64_t qp :6; + u_int64_t p1 :6; + u_int64_t ta :1; + u_int64_t f2 :7; + u_int64_t fclass7c:7; + u_int64_t p2 :6; + u_int64_t fc2 :2; + u_int64_t resv2 :2; + u_int64_t op :4; + } F5; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t p2 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t q :1; + u_int64_t op :4; + } F6; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t resv7 :7; + u_int64_t f3 :7; + u_int64_t p2 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t q :1; + u_int64_t op :4; + } F7; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t resv1 :1; + u_int64_t op :4; + } F8; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t f3 :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t resv3 :3; + u_int64_t op :4; + } F9; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t resv7 :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t resv1 :1; + u_int64_t op :4; + } F10; + struct { + u_int64_t qp :6; + u_int64_t f1 :7; + u_int64_t f2 :7; + u_int64_t resv7 :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t resv3 :2; + u_int64_t op :4; + } F11; + struct { + u_int64_t qp :6; + u_int64_t resv7 :7; + u_int64_t amask7b :7; + u_int64_t omask7c :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t resv1 :1; + u_int64_t op :4; + } F12; + struct { + u_int64_t qp :6; + u_int64_t resv21 :7; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t resv1 :1; + u_int64_t op :4; + } F13; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv1 :1; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t sf :2; + u_int64_t s :1; + u_int64_t op :4; + } F14; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv1 :1; + u_int64_t x6 :6; + u_int64_t x :1; + u_int64_t resv2 :2; + u_int64_t i :1; + u_int64_t op :4; + } F15; + struct { + u_int64_t qp :6; + u_int64_t imm20a :20; + u_int64_t resv1 :1; + u_int64_t x6 :6; + u_int64_t x3 :3; + u_int64_t i :1; + u_int64_t op :4; + } X1; + struct { + u_int64_t qp :6; + u_int64_t r1 :7; + u_int64_t imm7b :7; + u_int64_t vc :1; + u_int64_t ic :1; + u_int64_t imm5c :5; + u_int64_t imm9d :9; + u_int64_t i :1; + u_int64_t op :4; + } X2; + u_int64_t ins; +}; + +#endif /* _MACHINE_INST_H_ */ diff --git a/sys/ia64/include/ipl.h b/sys/ia64/include/ipl.h index 2a021eb..bb62be4 100644 --- a/sys/ia64/include/ipl.h +++ b/sys/ia64/include/ipl.h @@ -29,91 +29,12 @@ #ifndef _MACHINE_IPL_H_ #define _MACHINE_IPL_H_ - -#include /* for pal inlines */ - /* * Software interrupt bit numbers */ -#define SWI_TTY 0 -#define SWI_NET 1 -#define SWI_CAMNET 2 -#define SWI_CAMBIO 3 -#define SWI_VM 4 -#define SWI_CLOCK 5 -#define SWI_TQ 6 #define NSWI 32 #define NHWI 0 -extern u_int32_t ipending; - -#define getcpl() (alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) - -#define SPLDOWN(name, pri) \ - \ -static __inline int name(void) \ -{ \ - return 0; \ -} - -SPLDOWN(splsoftclock, SOFT) -SPLDOWN(splsoft, SOFT) - -#define SPLUP(name, pri) \ - \ -static __inline int name(void) \ -{ \ - return 0; \ -} - -SPLUP(splsoftcam, SOFT) -SPLUP(splsoftnet, SOFT) -SPLUP(splsoftvm, SOFT) -SPLUP(splsofttq, SOFT) -SPLUP(splnet, IO) -SPLUP(splbio, IO) -SPLUP(splcam, IO) -SPLUP(splimp, IO) -SPLUP(spltty, IO) -SPLUP(splvm, IO) -SPLUP(splclock, CLOCK) -SPLUP(splstatclock, CLOCK) -SPLUP(splhigh, HIGH) - -static __inline void -spl0(void) -{ - if (ipending) - do_sir(); /* lowers ipl to SOFT */ -} - -static __inline void -splx(int s) -{ -} - -extern void setdelayed(void); -extern void setsofttty(void); -extern void setsoftnet(void); -extern void setsoftcamnet(void); -extern void setsoftcambio(void); -extern void setsoftvm(void); -extern void setsofttq(void); -extern void setsoftclock(void); - -extern void schedsofttty(void); -extern void schedsoftnet(void); -extern void schedsoftcamnet(void); -extern void schedsoftcambio(void); -extern void schedsoftvm(void); -extern void schedsofttq(void); -extern void schedsoftclock(void); - -#if 0 -/* XXX bogus */ -extern unsigned cpl; /* current priority level mask */ -#endif - /* * Interprocessor interrupts for SMP. */ diff --git a/sys/ia64/include/pcpu.h b/sys/ia64/include/pcpu.h index 87c9fe5..eb88422 100644 --- a/sys/ia64/include/pcpu.h +++ b/sys/ia64/include/pcpu.h @@ -54,6 +54,7 @@ struct globaldata { int gd_inside_intr; u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */ u_int64_t gd_pending_ipis; /* pending IPI events */ + struct pmap *gd_current_pmap; /* which pmap is active */ u_int32_t gd_next_asn; /* next ASN to allocate */ u_int32_t gd_current_asngen; /* ASN rollover check */ u_int32_t gd_intr_nesting_level; /* interrupt recursion */ diff --git a/sys/ia64/include/pmap.h b/sys/ia64/include/pmap.h index edb7ec5..e80bda0 100644 --- a/sys/ia64/include/pmap.h +++ b/sys/ia64/include/pmap.h @@ -168,11 +168,10 @@ struct md_page { struct pmap { TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ + u_int64_t pm_rid; /* base RID for pmap */ int pm_count; /* reference count */ int pm_flags; /* pmap flags */ int pm_active; /* active flag */ - int pm_asn; /* address space number */ - u_int pm_asngen; /* generation number of pm_asn */ struct pmap_statistics pm_stats; /* pmap statistics */ struct vm_page *pm_ptphint; /* pmap ptp hint */ }; @@ -209,7 +208,6 @@ extern vm_offset_t avail_start; extern vm_offset_t clean_eva; extern vm_offset_t clean_sva; extern vm_offset_t phys_avail[]; -extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; @@ -223,8 +221,7 @@ unsigned *pmap_pte __P((pmap_t, vm_offset_t)) __pure2; vm_page_t pmap_use_pt __P((pmap_t, vm_offset_t)); void pmap_set_opt __P((unsigned *)); void pmap_set_opt_bsp __P((void)); -void pmap_deactivate __P((struct proc *p)); -void pmap_emulate_reference __P((struct proc *p, vm_offset_t v, int user, int write)); +struct pmap *pmap_install __P((struct pmap *pmap)); #endif /* _KERNEL */ -- cgit v1.1