emulate_load_int (unsigned long ifa, load_store_t ld, struct pt_regs *regs)
{
unsigned int len = 1 << ld.x6_sz;
+ unsigned long val = 0;
/*
* r0, as target, doesn't need to be checked because Illegal Instruction
*/
/*
- * ldX.a we don't try to emulate anything but we must invalidate the ALAT entry.
+ * ldX.a we will emulate load and also invalidate the ALAT entry.
* See comment below for explanation on how we handle ldX.a
*/
- if (ld.x6_op != 0x2) {
- unsigned long val = 0;
- if (len != 2 && len != 4 && len != 8) {
- DPRINT("unknown size: x6=%d\n", ld.x6_sz);
- return -1;
- }
- /* this assumes little-endian byte-order: */
- if (copy_from_user(&val, (void *) ifa, len))
- return -1;
- setreg(ld.r1, val, 0, regs);
+ if (len != 2 && len != 4 && len != 8) {
+ DPRINT("unknown size: x6=%d\n", ld.x6_sz);
+ return -1;
}
+ /* this assumes little-endian byte-order: */
+ if (copy_from_user(&val, (void *) ifa, len))
+ return -1;
+ setreg(ld.r1, val, 0, regs);
/*
* check for updates on any kind of loads
* store & shift to temporary;
* r1=temporary
*
- * So int this case, you would get the right value is r1 but the wrong info in
+ * So in this case, you would get the right value is r1 but the wrong info in
* the ALAT. Notice that you could do it in reverse to finish with address 3
* but you would still get the size wrong. To get the size right, one needs to
* execute exactly the same kind of load. You could do it from a aligned
* So no matter what, it is not possible to emulate an advanced load
* correctly. But is that really critical ?
*
+ * We will always convert ld.a into a normal load with ALAT invalidated. This
+ * will enable compiler to do optimization where certain code path after ld.a
+ * is not required to have ld.c/chk.a, e.g., code path with no intervening stores.
*
- * Now one has to look at how ld.a is used, one must either do a ld.c.* or
- * chck.a.* to reuse the value stored in the ALAT. Both can "fail" (meaning no
+ * If there is a store after the advanced load, one must either do a ld.c.* or
+ * chk.a.* to reuse the value stored in the ALAT. Both can "fail" (meaning no
* entry found in ALAT), and that's perfectly ok because:
*
* - ld.c.*, if the entry is not present a normal load is executed
*
* In either case, the load can be potentially retried in another form.
*
- * So it's okay NOT to do any actual load on an unaligned ld.a. However the ALAT
- * must be invalidated for the register (so that's chck.a.*,ld.c.* don't pick up
- * a stale entry later) The register base update MUST also be performed.
- *
- * Now what is the content of the register and its NaT bit in the case we don't
- * do the load ? EAS2.4, says (in case an actual load is needed)
- *
- * - r1 = [r3], Nat = 0 if succeeds
- * - r1 = 0 Nat = 0 if trying to access non-speculative memory
- *
- * For us, there is nothing to do, because both ld.c.* and chk.a.* are going to
- * retry and thus eventually reload the register thereby changing Nat and
- * register content.
+ * ALAT must be invalidated for the register (so that chk.a or ld.c don't pick
+ * up a stale entry later). The register base update MUST also be performed.
*/
/*