case GETSEG: return LIT0 && SZ2 && CC0 && Se1 && TR2 && N3 && XOTHER;
case USESEG: return LIT0 && SZ0 && CC0 && TR1 && TR2 && N3 && XOTHER;
case NOP: return LIT0 && SZ0 && CC0 && N1 && N2 && N3 && XOTHER;
+ case LOCK: return LIT0 && SZ0 && CC0 && N1 && N2 && N3 && XOTHER;
case GETF: return LIT0 && SZ42 && CCr && TR1 && N2 && N3 && XOTHER;
case PUTF: return LIT0 && SZ42 && CCw && TR1 && N2 && N3 && XOTHER;
case GET: return LIT0 && SZi && CC0 && AS1 && TR2 && N3 && XOTHER;
case LEA1: return "LEA1";
case LEA2: return "LEA2";
case NOP: return "NOP";
+ case LOCK: return "LOCK";
case GET: return "GET";
case PUT: return "PUT";
case GETF: return "GETF";
VG_(pp_UOperand)(u, 2, 4, False);
break;
- case NOP:
+ case NOP: case LOCK:
break;
case FPU_W:
case LEA2: RD(1); RD(2); WR(3); break;
case NOP: case FPU: case INCEIP: case CALLM_S: case CALLM_E:
- case CLEAR: case CALLM: break;
+ case CLEAR: case CALLM: case LOCK: break;
case CCALL:
if (u->argc > 0) RD(1);
case LEA1:
case LEA2:
case NOP:
+ case LOCK:
case PUT:
case LOAD:
case STORE:
static void eraser_mem_help_write_4(Addr a, UInt val) REGPARM(2);
static void eraser_mem_help_write_N(Addr a, UInt size) REGPARM(2);
+static void bus_lock(void);
+static void bus_unlock(void);
+
static
void eraser_pre_mem_read(CorePart part, ThreadState* tst,
Char* s, UInt base, UInt size )
Int t_size = INVALID_TEMPREG;
Int ntemps;
Bool *stackref = NULL;
+ Bool locked = False; /* lock prefix */
cb = VG_(alloc_UCodeBlock)();
cb->nextTemp = cb_in->nextTemp;
case NOP: case CALLM_S: case CALLM_E:
break;
+ case LOCK:
+ locked = True;
+ uInstr0(cb, CCALL, 0);
+ uCCall(cb, (Addr)bus_lock, 0, 0, False);
+ break;
+
+ case JMP: case INCEIP:
+ if (locked) {
+ uInstr0(cb, CCALL, 0);
+ uCCall(cb, (Addr)bus_unlock, 0, 0, False);
+ }
+ locked = False;
+ VG_(copy_UInstr)(cb, u_in);
+ break;
+
case GET:
sk_assert(u_in->tag1 == ArchReg);
sk_assert(u_in->tag2 == TempReg);
clearTLS(joinee);
}
+static Int __BUS_HARDWARE_LOCK__;
+
+static void bus_lock(void)
+{
+ ThreadId tid = VG_(get_current_tid)();
+ eraser_pre_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
+ eraser_post_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
+}
+
+static void bus_unlock(void)
+{
+ ThreadId tid = VG_(get_current_tid)();
+ eraser_post_mutex_unlock(tid, &__BUS_HARDWARE_LOCK__);
+}
+
/*--------------------------------------------------------------------*/
/*--- Client requests ---*/
/*--------------------------------------------------------------------*/
VG_(register_compact_helper)((Addr) & eraser_mem_help_write_4);
VG_(register_noncompact_helper)((Addr) & eraser_mem_help_write_N);
+ VG_(register_noncompact_helper)((Addr) & bus_lock);
+ VG_(register_noncompact_helper)((Addr) & bus_unlock);
+
for(i = 0; i < LOCKSET_HASH_SZ; i++)
lockset_hash[i] = NULL;