case 0x1:
                             return new Enterx(machInst);
                           case 0x2:
-                            return new WarnUnimplemented("clrex", machInst);
+                            return new Clrex(machInst);
                           case 0x4:
                             return new WarnUnimplemented("dsb", machInst);
                           case 0x5:
 
                 } else if (op1 == 0x57) {
                     switch (op2) {
                       case 0x1:
-                        return new WarnUnimplemented("clrex", machInst);
+                        return new Clrex(machInst);
                       case 0x4:
                         return new WarnUnimplemented("dsb", machInst);
                       case 0x5:
 
     decoder_output += ImmOpConstructor.subst(setendIop)
     exec_output += PredOpExecute.subst(setendIop)
 
+    clrexCode = '''
+        unsigned memAccessFlags = ArmISA::TLB::Clrex|3|Request::LLSC;
+        fault = xc->read(0, (uint32_t&)Mem, memAccessFlags);
+    '''
+    clrexIop = InstObjParams("clrex", "Clrex","PredOp",
+                             { "code": clrexCode,
+                               "predicate_test": predicateTest },[])
+    header_output += BasicDeclare.subst(clrexIop)
+    decoder_output += BasicConstructor.subst(clrexIop)
+    exec_output += PredOpExecute.subst(clrexIop)
+
     cpsCode = '''
     uint32_t mode = bits(imm, 4, 0);
     uint32_t f = bits(imm, 5);
 
 
     DPRINTF(TLBVerbose, "CPSR is user:%d UserMode:%d\n", cpsr.mode == MODE_USER, flags
             & UserMode);
+    // If this is a clrex instruction, provide a PA of 0 with no fault
+    // This will force the monitor to set the tracked address to 0
+    // a bit of a hack but this effectively clrears this processors monitor
+    if (flags & Clrex){
+       req->setPaddr(0);
+       return NoFault;
+    }
     if (!is_fetch) {
         assert(flags & MustBeOne);
         if (sctlr.a || !(flags & AllowUnaligned)) {
 
         // Because zero otherwise looks like a valid setting and may be used
         // accidentally, this bit must be non-zero to show it was used on
         // purpose.
-        MustBeOne = 0x20
+        MustBeOne = 0x20,
+        Clrex = 0x40
     };
   protected:
     typedef std::multimap<Addr, int> PageTable;