diff -urN libpfm-3.0/ChangeLog libpfm-3.1/ChangeLog
--- libpfm-3.0/ChangeLog	2003-11-26 14:25:22.000000000 -0800
+++ libpfm-3.1/ChangeLog	2004-06-24 11:57:27.352903128 -0700
@@ -1,3 +1,16 @@
+2004-06-24 Stephane Eranian <eranian@hpl.hp.com>
+	* fixed Itanium2 events tables L2_FORCE_RECIRC_*
+	and L2_L3ACCESS_* events can only be measured by PMC4
+
+	* fixed pfm_*_get_event_counters(). It would always
+	return the counter mask for event index 0.
+
+2004-02-12 Stephane Eranian <eranian@hpl.hp.com>
+	* fixed a bug in pfmlib_itanium2.c which cause measurements
+	  using opcode matching with an event different from
+	  IA64_TAGGED_INST_RETIRED* to return wrong results, i.e.,
+	  opcode filter was ignored.
+
 2003-11-21 Stephane Eranian <eranian@hpl.hp.com>
 	* changed interface to pfm_get_impl_*() to use
 	  a cleaner definition for bitmasks. pfmlib_regmask_t is
diff -urN libpfm-3.0/include/perfmon/pfmlib.h libpfm-3.1/include/perfmon/pfmlib.h
--- libpfm-3.0/include/perfmon/pfmlib.h	2003-12-01 11:25:34.000000000 -0800
+++ libpfm-3.1/include/perfmon/pfmlib.h	2004-06-24 12:14:02.351173689 -0700
@@ -33,7 +33,7 @@
 #include <perfmon/pfmlib_os.h>
 #include <perfmon/pfmlib_comp.h>
 
-#define PFMLIB_VERSION		(3 << 16 | 0)
+#define PFMLIB_VERSION		(3 << 16 | 1)
 #define PFMLIB_MAJ_VERSION(v)	((v)>>16)
 #define PFMLIB_MIN_VERSION(v)	((v) & 0xffff)
 
diff -urN libpfm-3.0/lib/Makefile libpfm-3.1/lib/Makefile
--- libpfm-3.0/lib/Makefile	2003-10-27 14:42:54.000000000 -0800
+++ libpfm-3.1/lib/Makefile	2004-06-24 12:01:34.245026403 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2002-2003 Hewlett-Packard Co
+# Copyright (C) 2002-2004 Hewlett-Packard Co
 # Contributed by Stephane Eranian <eranian@hpl.hp.com>
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -54,11 +54,13 @@
 ifeq ($(CONFIG_PFMLIB_ITANIUM),y)
 SRCS   += pfmlib_itanium.c
 CFLAGS += -DCONFIG_PFMLIB_ITANIUM
+pfmlib_itanium.o : itanium_events.h
 endif
 
 ifeq ($(CONFIG_PFMLIB_ITANIUM2),y)
 SRCS   += pfmlib_itanium2.c
 CFLAGS += -DCONFIG_PFMLIB_ITANIUM2
+pfmlib_itanium2.o : itanium2_events.h
 endif
 
 INCDIR=-I$(PFMINCDIR) -I.
diff -urN libpfm-3.0/lib/itanium2_events.h libpfm-3.1/lib/itanium2_events.h
--- libpfm-3.0/lib/itanium2_events.h	2003-10-27 14:43:00.000000000 -0800
+++ libpfm-3.1/lib/itanium2_events.h	2004-06-24 11:55:54.434980812 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2002-2003 Hewlett-Packard Co
+ * Copyright (C) 2002-2004 Hewlett-Packard Co
  * Contributed by Stephane Eranian <eranian@hpl.hp.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -732,31 +732,31 @@
 #define PME_ITA2_L2_FILLB_FULL_THIS 350
 { "L2_FILLB_FULL_THIS", {0xbf}, 0xf0, 1, {0x4520000}, "L2D Fill Buffer Is Full -- L2 Fill buffer is full"},
 #define PME_ITA2_L2_FORCE_RECIRC_ANY 351
-{ "L2_FORCE_RECIRC_ANY", {0xb4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count forced recirculates regardless of cause. SMC_HIT, TRAN_PREF & SNP_OR_L3 will not be included here."},
+{ "L2_FORCE_RECIRC_ANY", {0xb4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count forced recirculates regardless of cause. SMC_HIT, TRAN_PREF & SNP_OR_L3 will not be included here."},
 #define PME_ITA2_L2_FORCE_RECIRC_FILL_HIT 352
-{ "L2_FORCE_RECIRC_FILL_HIT", {0x900b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss which hit in the fill buffer."},
+{ "L2_FORCE_RECIRC_FILL_HIT", {0x900b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss which hit in the fill buffer."},
 #define PME_ITA2_L2_FORCE_RECIRC_FRC_RECIRC 353
-{ "L2_FORCE_RECIRC_FRC_RECIRC", {0xe00b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when a force recirculate already existed"},
+{ "L2_FORCE_RECIRC_FRC_RECIRC", {0xe00b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when a force recirculate already existed"},
 #define PME_ITA2_L2_FORCE_RECIRC_IPF_MISS 354
-{ "L2_FORCE_RECIRC_IPF_MISS", {0xa00b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- caused by L2 miss when instruction prefetch buffer miss already existed"},
+{ "L2_FORCE_RECIRC_IPF_MISS", {0xa00b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- caused by L2 miss when instruction prefetch buffer miss already existed"},
 #define PME_ITA2_L2_FORCE_RECIRC_L1W 355
-{ "L2_FORCE_RECIRC_L1W", {0x200b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by forced limbo"},
+{ "L2_FORCE_RECIRC_L1W", {0x200b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by forced limbo"},
 #define PME_ITA2_L2_FORCE_RECIRC_OZQ_MISS 356
-{ "L2_FORCE_RECIRC_OZQ_MISS", {0xc00b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when an OZQ miss already existed"},
+{ "L2_FORCE_RECIRC_OZQ_MISS", {0xc00b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when an OZQ miss already existed"},
 #define PME_ITA2_L2_FORCE_RECIRC_SAME_INDEX 357
-{ "L2_FORCE_RECIRC_SAME_INDEX", {0xd00b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when a miss to the same index already existed"},
+{ "L2_FORCE_RECIRC_SAME_INDEX", {0xd00b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- caused by an L2 miss when a miss to the same index already existed"},
 #define PME_ITA2_L2_FORCE_RECIRC_SMC_HIT 358
-{ "L2_FORCE_RECIRC_SMC_HIT", {0x100b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by SMC hits due to an ifetch and load to same cache line or a pending WT store"},
+{ "L2_FORCE_RECIRC_SMC_HIT", {0x100b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by SMC hits due to an ifetch and load to same cache line or a pending WT store"},
 #define PME_ITA2_L2_FORCE_RECIRC_SNP_OR_L3 359
-{ "L2_FORCE_RECIRC_SNP_OR_L3", {0x600b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by a snoop or L3 issue"},
+{ "L2_FORCE_RECIRC_SNP_OR_L3", {0x600b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by a snoop or L3 issue"},
 #define PME_ITA2_L2_FORCE_RECIRC_TAG_NOTOK 360
-{ "L2_FORCE_RECIRC_TAG_NOTOK", {0x400b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by L2 hits caused by in flight snoops, stores with a sibling miss to the same index, sibling probe to the same line or pending sync.ia instructions."},
+{ "L2_FORCE_RECIRC_TAG_NOTOK", {0x400b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by L2 hits caused by in flight snoops, stores with a sibling miss to the same index, sibling probe to the same line or pending sync.ia instructions."},
 #define PME_ITA2_L2_FORCE_RECIRC_TRAN_PREF 361
-{ "L2_FORCE_RECIRC_TRAN_PREF", {0x500b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by transforms to prefetches"},
+{ "L2_FORCE_RECIRC_TRAN_PREF", {0x500b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by transforms to prefetches"},
 #define PME_ITA2_L2_FORCE_RECIRC_VIC_BUF_FULL 362
-{ "L2_FORCE_RECIRC_VIC_BUF_FULL", {0xb00b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss with victim buffer full"},
+{ "L2_FORCE_RECIRC_VIC_BUF_FULL", {0xb00b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss with victim buffer full"},
 #define PME_ITA2_L2_FORCE_RECIRC_VIC_PEND 363
-{ "L2_FORCE_RECIRC_VIC_PEND", {0x800b4}, 0xf0, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss with pending victim"},
+{ "L2_FORCE_RECIRC_VIC_PEND", {0x800b4}, 0x10, 4, {0x4220007}, "Forced Recirculates -- count only those caused by an L2 miss with pending victim"},
 #define PME_ITA2_L2_GOT_RECIRC_IFETCH_ANY 364
 { "L2_GOT_RECIRC_IFETCH_ANY", {0x800ba}, 0xf0, 1, {0x4420007}, "Instruction Fetch Recirculates Received by L2D -- Instruction fetch recirculates received by L2"},
 #define PME_ITA2_L2_GOT_RECIRC_OZQ_ACC 365
@@ -788,21 +788,21 @@
 #define PME_ITA2_L2_ISSUED_RECIRC_OZQ_ACC 378
 { "L2_ISSUED_RECIRC_OZQ_ACC", {0xb5}, 0xf0, 1, {0x4220007}, "Count Number of Times a Recirculate Issue Was Attempted and Not Preempted"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_ANY 379
-{ "L2_L3ACCESS_CANCEL_ANY", {0x900b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- count cancels due to any reason. This umask will count more than the sum of all the other umasks. It will count things that weren't committed accesses when they reached L1w, but the L2 attempted to bypass them to the L3 anyway (speculatively). This will include accesses made repeatedly while the main pipeline is stalled and the L1d is attempting to recirculate an access down the L1d pipeline. Thus, an access could get counted many times before it really does get bypassed to the L3. It is a measure of how many times we asserted a request to the L3 but didn't confirm it."},
+{ "L2_L3ACCESS_CANCEL_ANY", {0x900b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- count cancels due to any reason. This umask will count more than the sum of all the other umasks. It will count things that weren't committed accesses when they reached L1w, but the L2 attempted to bypass them to the L3 anyway (speculatively). This will include accesses made repeatedly while the main pipeline is stalled and the L1d is attempting to recirculate an access down the L1d pipeline. Thus, an access could get counted many times before it really does get bypassed to the L3. It is a measure of how many times we asserted a request to the L3 but didn't confirm it."},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_DFETCH 380
-{ "L2_L3ACCESS_CANCEL_DFETCH", {0xa00b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- data fetches"},
+{ "L2_L3ACCESS_CANCEL_DFETCH", {0xa00b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- data fetches"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_EBL_REJECT 381
-{ "L2_L3ACCESS_CANCEL_EBL_REJECT", {0x800b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- ebl rejects"},
+{ "L2_L3ACCESS_CANCEL_EBL_REJECT", {0x800b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- ebl rejects"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_FILLD_FULL 382
-{ "L2_L3ACCESS_CANCEL_FILLD_FULL", {0x200b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- filld being full"},
+{ "L2_L3ACCESS_CANCEL_FILLD_FULL", {0x200b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- filld being full"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_IFETCH 383
 { "L2_L3ACCESS_CANCEL_IFETCH", {0xb00b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- instruction fetches"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_INV_L3_BYP 384
-{ "L2_L3ACCESS_CANCEL_INV_L3_BYP", {0x600b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- invalid L3 bypasses"},
+{ "L2_L3ACCESS_CANCEL_INV_L3_BYP", {0x600b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- invalid L3 bypasses"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_SPEC_L3_BYP 385
-{ "L2_L3ACCESS_CANCEL_SPEC_L3_BYP", {0x100b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- speculative L3 bypasses"},
+{ "L2_L3ACCESS_CANCEL_SPEC_L3_BYP", {0x100b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- speculative L3 bypasses"},
 #define PME_ITA2_L2_L3ACCESS_CANCEL_UC_BLOCKED 386
-{ "L2_L3ACCESS_CANCEL_UC_BLOCKED", {0x500b0}, 0xf0, 1, {0x4120007}, "Canceled L3 Accesses -- Uncacheable blocked L3 Accesses"},
+{ "L2_L3ACCESS_CANCEL_UC_BLOCKED", {0x500b0}, 0x10, 1, {0x4120007}, "Canceled L3 Accesses -- Uncacheable blocked L3 Accesses"},
 #define PME_ITA2_L2_MISSES 387
 { "L2_MISSES", {0xcb}, 0xf0, 1, {0xf00007}, "L2 Misses"},
 #define PME_ITA2_L2_OPS_ISSUED_FP_LOAD 388
diff -urN libpfm-3.0/lib/pfmlib_common.c libpfm-3.1/lib/pfmlib_common.c
--- libpfm-3.0/lib/pfmlib_common.c	2003-12-01 11:33:31.000000000 -0800
+++ libpfm-3.1/lib/pfmlib_common.c	2004-06-24 12:03:30.812602594 -0700
@@ -387,16 +387,16 @@
 pfm_print_event_info(const char *name, int (*pf)(const char *fmt,...))
 {
 	unsigned long number, vcode;
-	pfmlib_regmask_t cmask;
+	pfmlib_regmask_t cmask, impl_counters;
         int code, ret;
 	int code_is_used = 1, event_is_digit = 0;
-	unsigned int idx, next_idx, n_counters, i;
+	unsigned int idx, next_idx, n, num_counters, i;
 
 	if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT;
 
 	if (name == NULL || pf == NULL) return PFMLIB_ERR_INVAL;
 
-	pfm_current->get_num_counters(&n_counters);
+	pfm_current->get_num_counters(&n);
 
 	/* we can't quite use pfm_findevent() because we need to try
 	 * both ways systematically.
@@ -424,6 +424,7 @@
 
 	if (ret != PFMLIB_SUCCESS) return PFMLIB_ERR_NOTFOUND;
 
+	pfm_current->get_num_counters(&num_counters);
 start_loop:
 	do {
 		code  = pfm_current->get_event_code(idx);
@@ -439,8 +440,9 @@
 		(*pf)(	"PMD/PMC: [ ");
 
 		pfm_current->get_event_counters(idx, &cmask);
-
-		for (i=0; i < n_counters; i++) {
+		n = num_counters;
+		for (i=0; n; i++) {
+			if (PFMLIB_REGMASK_ISSET(&impl_counters, i)) n--;
 			if (PFMLIB_REGMASK_ISSET(&cmask, i)) (*pf)("%d ", i);
 		}
 		(*pf)(	"]\n");
@@ -463,8 +465,8 @@
 int
 pfm_print_event_info_byindex(unsigned int v, int (*pf)(const char *fmt,...))
 {
-	pfmlib_regmask_t cmask;
-	unsigned int i, n_counters;
+	pfmlib_regmask_t cmask, impl_counters;
+	unsigned int i, n;
 
 	if (PFMLIB_INITIALIZED() == 0) return PFMLIB_ERR_NOINIT;
 
@@ -479,10 +481,12 @@
 	
 	(*pf)(	"PMD/PMC: [ ");
 
-	pfm_current->get_num_counters(&n_counters);
+	pfm_current->get_num_counters(&n);
 	pfm_current->get_event_counters(v, &cmask);
+	pfm_current->get_impl_counters(&impl_counters);
 
-	for (i=0; i < n_counters; i++) {
+	for (i=0; n; i++) {
+		if (PFMLIB_REGMASK_ISSET(&impl_counters, i)) n--;
 		if (PFMLIB_REGMASK_ISSET(&cmask, i)) (*pf)("%d ", i);
 	}
 	(*pf)(	"]\n");
@@ -494,7 +498,6 @@
 	return PFMLIB_SUCCESS;
 }
 
-
 int
 pfm_dispatch_events(pfmlib_input_param_t *inp, void *model_in, pfmlib_output_param_t *outp, void *model_out)
 {
diff -urN libpfm-3.0/lib/pfmlib_generic_ia64.c libpfm-3.1/lib/pfmlib_generic_ia64.c
--- libpfm-3.0/lib/pfmlib_generic_ia64.c	2003-11-26 14:21:17.000000000 -0800
+++ libpfm-3.1/lib/pfmlib_generic_ia64.c	2004-06-24 11:45:55.373276438 -0700
@@ -324,13 +324,13 @@
 static void
 pfm_gen_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
 {
-	unsigned int i = 0;
+	unsigned int i;
 	unsigned long m;
 
 	memset(counters, 0, sizeof(*counters));
 
-	m = generic_pe[i].pme_counters;
-	for(; m ; i++, m>>=1) {
+	m = generic_pe[j].pme_counters;
+	for(i=0; m ; i++, m>>=1) {
 		if (m & 0x1) PFMLIB_REGMASK_SET(counters, i);
 	}
 }
diff -urN libpfm-3.0/lib/pfmlib_itanium.c libpfm-3.1/lib/pfmlib_itanium.c
--- libpfm-3.0/lib/pfmlib_itanium.c	2003-11-26 14:21:49.000000000 -0800
+++ libpfm-3.1/lib/pfmlib_itanium.c	2004-06-24 11:45:37.835013872 -0700
@@ -1073,13 +1073,13 @@
 static void
 pfm_ita_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
 {
-	unsigned int i = 0;
+	unsigned int i;
 	unsigned long m;
 
 	memset(counters, 0, sizeof(*counters));
 
-	m =itanium_pe[i].pme_counters;
-	for(; m ; i++, m>>=1) {
+	m =itanium_pe[j].pme_counters;
+	for(i=0; m ; i++, m>>=1) {
 		if (m & 0x1) PFMLIB_REGMASK_SET(counters, i);
 	}
 }
diff -urN libpfm-3.0/lib/pfmlib_itanium2.c libpfm-3.1/lib/pfmlib_itanium2.c
--- libpfm-3.0/lib/pfmlib_itanium2.c	2003-11-26 14:22:36.000000000 -0800
+++ libpfm-3.1/lib/pfmlib_itanium2.c	2004-06-24 12:11:27.820323646 -0700
@@ -1,7 +1,7 @@
 /*
  * pfmlib_itanium2.c : support for the Itanium2 PMU family
  *
- * Copyright (C) 2002-2003 Hewlett-Packard Co
+ * Copyright (C) 2002-2004 Hewlett-Packard Co
  * Contributed by Stephane Eranian <eranian@hpl.hp.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -209,22 +209,31 @@
  * 4 IBR when non-fine mode is not possible.
  *
  * This function returns:
- * 	the number of events match the IA64_INST_RETIRED code
+ * 	- the number of events match the IA64_INST_RETIRED code
+ * 	- in retired_mask the bottom 4 bits indicates which of the 4 INST_RETIRED event
+ * 	is present
  */
 static unsigned int
-check_inst_retired_events(pfmlib_input_param_t *inp)
+check_inst_retired_events(pfmlib_input_param_t *inp, unsigned long *retired_mask)
 {
 	int code;
 	int c;
 	unsigned int i, count, found = 0;
+	unsigned long umask, mask;
 
 	pfm_get_event_code(PME_ITA2_IA64_INST_RETIRED_THIS, &code);
 
 	count = inp->pfp_event_count;
+	mask  = 0;
 	for(i=0; i < count; i++) {
 		pfm_get_event_code(inp->pfp_events[i].event, &c);
-		if (c == code)  found++;
+		if (c == code)  {
+			pfm_ita2_get_event_umask(inp->pfp_events[i].event, &umask);
+			mask |= umask;
+			found++;
+		}
 	}
+	if (retired_mask) *retired_mask = mask;
 	return found;
 }
 
@@ -562,9 +571,6 @@
 		DPRINT(("I-EAR event with no info\n"));
 	}
 
-	/* sanity check on the mode */
-	if (param->pfp_ita2_iear.ear_mode < 0 || param->pfp_ita2_iear.ear_mode > 2) return PFMLIB_ERR_INVAL;
-
 	/*
 	 * case 2: ear_used=1, event is defined, we use the param info as it is more precise
 	 * case 4: ear_used=1, no event (free running I-EAR), use param info
@@ -578,13 +584,16 @@
 		reg.pmc10_ita2_tlb_reg.iear_ct      = 0x0;
 		reg.pmc10_ita2_tlb_reg.iear_umask   = param->pfp_ita2_iear.ear_umask;
 		reg.pmc10_ita2_tlb_reg.iear_ism     = param->pfp_ita2_iear.ear_ism;
-	} else {
+	} else if (param->pfp_ita2_iear.ear_mode == PFMLIB_ITA2_EAR_CACHE_MODE) {
 		/* if plm is 0, then assume not specified per-event and use default */
 		reg.pmc10_ita2_cache_reg.iear_plm   = param->pfp_ita2_iear.ear_plm ? param->pfp_ita2_iear.ear_plm : inp->pfp_dfl_plm;
 		reg.pmc10_ita2_cache_reg.iear_pm    = inp->pfp_flags & PFMLIB_PFP_SYSTEMWIDE ? 1 : 0;
 		reg.pmc10_ita2_cache_reg.iear_ct    = 0x1;
 		reg.pmc10_ita2_cache_reg.iear_umask = param->pfp_ita2_iear.ear_umask;
 		reg.pmc10_ita2_cache_reg.iear_ism   = param->pfp_ita2_iear.ear_ism;
+	} else {
+		DPRINT(("ALAT mode not supported in I-EAR mode\n"));
+		return PFMLIB_ERR_INVAL;
 	}
 
 	pc[pos].reg_num     = 10; /* PMC10 is I-EAR config register */
@@ -649,7 +658,10 @@
 	}
 
 	/* sanity check on the mode */
-	if (param->pfp_ita2_dear.ear_mode > 2) return PFMLIB_ERR_INVAL;
+	if (   param->pfp_ita2_dear.ear_mode != PFMLIB_ITA2_EAR_CACHE_MODE
+	    && param->pfp_ita2_dear.ear_mode != PFMLIB_ITA2_EAR_TLB_MODE
+	    && param->pfp_ita2_dear.ear_mode != PFMLIB_ITA2_EAR_ALAT_MODE)
+		return PFMLIB_ERR_INVAL;
 
 	/*
 	 * case 2: ear_used=1, event is defined, we use the param info as it is more precise
@@ -723,8 +735,8 @@
 		/*
 		 * will be constrained by PMC8
 		 */
-		has_1st_pair = has_2nd_pair = 0;
 		if (param->pfp_ita2_pmc8.opcm_used) {
+			has_1st_pair = has_2nd_pair = 0;
 			count = inp->pfp_event_count;
 			for(i=0; i < count; i++) {
 				if (inp->pfp_events[i].event == PME_ITA2_IA64_TAGGED_INST_RETIRED_IBRP0_PMC8) has_1st_pair=1;
@@ -750,7 +762,7 @@
 		/*
 		 * PMC9 can only be used to qualify IA64_INST_RETIRED_* events
 		 */
-		if (check_inst_retired_events(inp) != inp->pfp_event_count) return PFMLIB_ERR_FEATCOMB;
+		if (check_inst_retired_events(inp, NULL) != inp->pfp_event_count) return PFMLIB_ERR_FEATCOMB;
 
 		memset(pc+pos, 0, sizeof(pfmlib_reg_t));
 
@@ -1318,6 +1330,7 @@
 	unsigned int retired_only, retired_count, fine_mode, prefetch_count;
 	unsigned int n_intervals;
 	int base_idx = 0;
+	unsigned long retired_mask;
 
 	if (param == NULL) return PFMLIB_SUCCESS;
 
@@ -1333,7 +1346,7 @@
 
 	if (n_intervals < 1) return PFMLIB_ERR_IRRINVAL;
 	
-	retired_count  = check_inst_retired_events(inp);
+	retired_count  = check_inst_retired_events(inp, &retired_mask);
 	retired_only   = retired_count == inp->pfp_event_count;
 	prefetch_count = check_prefetch_events(inp);
 	fine_mode      = irr->rr_flags & PFMLIB_ITA2_RR_NO_FINE_MODE ?
@@ -1402,10 +1415,20 @@
 
 	count = orr->rr_nbr_used;
 	for (i=0; i < count; i++) {
-		if (orr->rr_br[i].reg_num == 0) reg.pmc14_ita2_reg.iarc_ibrp0 = 0;
-		if (orr->rr_br[i].reg_num == 2) reg.pmc14_ita2_reg.iarc_ibrp1 = 0;
-		if (orr->rr_br[i].reg_num == 4) reg.pmc14_ita2_reg.iarc_ibrp2 = 0;
-		if (orr->rr_br[i].reg_num == 6) reg.pmc14_ita2_reg.iarc_ibrp3 = 0;
+		switch(orr->rr_br[i].reg_num) {
+			case 0:
+				reg.pmc14_ita2_reg.iarc_ibrp0 = 0;
+				break;
+			case 2:
+				reg.pmc14_ita2_reg.iarc_ibrp1 = 0;
+				break;
+			case 4: 
+				reg.pmc14_ita2_reg.iarc_ibrp2 = 0;
+				break;
+			case 6:
+				reg.pmc14_ita2_reg.iarc_ibrp3 = 0;
+				break;
+		}
 	}
 
 	if (retired_only && (param->pfp_ita2_pmc8.opcm_used ||param->pfp_ita2_pmc9.opcm_used)) {
@@ -1425,6 +1448,16 @@
 
 	if (fine_mode) {
 		reg.pmc14_ita2_reg.iarc_fine = 1;
+	} else if (retired_only) {
+		unsigned long m;
+		/*
+		 * we need to check that the user provided all the events needed to cover
+		 * all the ibr pairs used to cover the range
+		 */
+		for(i=0; i < 4; i++) {
+			m = 1UL << i;
+			if ((reg.pmc_val & m) && (retired_mask & m) == 0) return PFMLIB_ERR_IRRINVAL;
+		}
 	}
 
 	/* initialize pmc request slot */
@@ -1471,7 +1504,7 @@
 	pfm_ita2_pmc_reg_t pmc13;
 	pfm_ita2_pmc_reg_t pmc14;
 	unsigned int i, pos = outp->pfp_pmc_count;
-	int iod_codes[4], dfl_val;
+	int iod_codes[4], dfl_val_pmc8, dfl_val_pmc9;
 	unsigned int n_intervals;
 	int ret;
 	int base_idx = 0;
@@ -1505,7 +1538,8 @@
 	 * if drange is used we do not know in advance which DBR will be used
 	 * therefore we need to apply dfl_val later
 	 */
-	dfl_val = param->pfp_ita2_pmc8.opcm_used || param->pfp_ita2_pmc9.opcm_used ? OP_USED : 0;
+	dfl_val_pmc8 = param->pfp_ita2_pmc8.opcm_used ? OP_USED : 0;
+	dfl_val_pmc9 = param->pfp_ita2_pmc9.opcm_used ? OP_USED : 0;
 
 	if (param->pfp_ita2_drange.rr_used == 1) {
 
@@ -1528,10 +1562,10 @@
 		 * Update iod_codes to reflect the use of the DBR constraint.
 		 */
 		for (i=0; i < orr->rr_nbr_used; i++) {
-			if (orr->rr_br[i].reg_num == 0) iod_codes[0] |= DR_USED | dfl_val;
-			if (orr->rr_br[i].reg_num == 2) iod_codes[1] |= DR_USED | dfl_val;
-			if (orr->rr_br[i].reg_num == 4) iod_codes[2] |= DR_USED | dfl_val;
-			if (orr->rr_br[i].reg_num == 6) iod_codes[3] |= DR_USED | dfl_val;
+			if (orr->rr_br[i].reg_num == 0) iod_codes[0] |= DR_USED | dfl_val_pmc8;
+			if (orr->rr_br[i].reg_num == 2) iod_codes[1] |= DR_USED | dfl_val_pmc9;
+			if (orr->rr_br[i].reg_num == 4) iod_codes[2] |= DR_USED | dfl_val_pmc8;
+			if (orr->rr_br[i].reg_num == 6) iod_codes[3] |= DR_USED | dfl_val_pmc9;
 		}
 
 	}
@@ -1565,13 +1599,18 @@
 		 * Update to reflect the use of the IBR constraint
 		 */
 		for (i=0; i < orr2->rr_nbr_used; i++) {
-			if (orr2->rr_br[i].reg_num == 0) iod_codes[0] |= IR_USED | dfl_val;
-			if (orr2->rr_br[i].reg_num == 2) iod_codes[1] |= IR_USED | dfl_val;
-			if (fine_mode == 0 && orr2->rr_br[i].reg_num == 4) iod_codes[2] |= IR_USED | dfl_val;
-			if (fine_mode == 0 && orr2->rr_br[i].reg_num == 6) iod_codes[3] |= IR_USED | dfl_val;
+			if (orr2->rr_br[i].reg_num == 0) iod_codes[0] |= IR_USED | dfl_val_pmc8;
+			if (orr2->rr_br[i].reg_num == 2) iod_codes[1] |= IR_USED | dfl_val_pmc9;
+			if (fine_mode == 0 && orr2->rr_br[i].reg_num == 4) iod_codes[2] |= IR_USED | dfl_val_pmc8;
+			if (fine_mode == 0 && orr2->rr_br[i].reg_num == 6) iod_codes[3] |= IR_USED | dfl_val_pmc9;
 		}
 	}
 
+	if (param->pfp_ita2_irange.rr_used == 0 && param->pfp_ita2_drange.rr_used ==0) {
+		iod_codes[0] = iod_codes[2] = dfl_val_pmc8;
+		iod_codes[1] = iod_codes[3] = dfl_val_pmc9;
+	}
+
 	/*
 	 * update the cfg dbrpX field. If we put a constraint on a cfg dbrp, then
 	 * we must enable it in the corresponding ena_dbrpX
@@ -1867,7 +1906,7 @@
 		(*pf)("Group  : None\n");
 	else {
 		unsigned long g = e->pme_qualifiers.pme_qual.pme_group;
-		const char *str =  g < 3 ? groups[g]: 0;
+		const char *str =  g < 3 ? groups[g]: "none";
 		(*pf)("Group  : %s\n", str);
 	}
 	if (e->pme_qualifiers.pme_qual.pme_set == 0xf)
@@ -1955,13 +1994,13 @@
 static void
 pfm_ita2_get_event_counters(unsigned int j, pfmlib_regmask_t *counters)
 {
-	unsigned int i = 0;
+	unsigned int i;
 	unsigned long m;
 
 	memset(counters, 0, sizeof(*counters));
 
-	m =itanium2_pe[i].pme_counters;
-	for(; m ; i++, m>>=1) {
+	m =itanium2_pe[j].pme_counters;
+	for(i=0; m ; i++, m>>=1) {
 		if (m & 0x1) PFMLIB_REGMASK_SET(counters, i);
 	}
 }
@@ -2012,15 +2051,15 @@
 }
 
 static void
-pfm_ita2_num_pmcs(unsigned int *width)
+pfm_ita2_num_pmcs(unsigned int *num)
 {
-	*width = PMU_ITA2_NUM_PMCS;
+	*num = PMU_ITA2_NUM_PMCS;
 }
 
 static void
-pfm_ita2_num_pmds(unsigned int *width)
+pfm_ita2_num_pmds(unsigned int *num)
 {
-	*width = PMU_ITA2_NUM_PMDS;
+	*num = PMU_ITA2_NUM_PMDS;
 }
 
 
