diff --git a/.gitattributes b/.gitattributes
index 4cce1ecd1d8a876251dd495c11e3206e7080abdf..43eda93c14250ace45830aa45b04276db6f12c04 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -233,10 +233,12 @@ libMEDSannotation/src/Makefile -text
 libMEDSannotation/src/VirtualOffset.cpp -text
 libtransform/Makefile -text
 libtransform/include/integertransform.hpp -text
+libtransform/include/integertransform64.hpp -text
 libtransform/include/leapattern.hpp -text
 libtransform/include/transform.hpp -text
 libtransform/src/Makefile -text
 libtransform/src/integertransform.cpp -text
+libtransform/src/integertransform64.cpp -text
 libtransform/src/leapattern.cpp -text
 libtransform/src/transform.cpp -text
 libtransform/tests/Makefile -text
diff --git a/libtransform/include/integertransform64.hpp b/libtransform/include/integertransform64.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7931a93a53b35ec8cca4cb4612f2858a5ab1bbde
--- /dev/null
+++ b/libtransform/include/integertransform64.hpp
@@ -0,0 +1,65 @@
+#ifndef _LIBTRANSFORM_INTEGERTRANSFORM64_H_
+#define _LIBTRANSFORM_INTEGERTRANSFORM64_H_
+
+#include "transform.hpp"
+#include "MEDS_Register.hpp"
+#include "VirtualOffset.hpp"
+
+namespace libTransform
+{
+
+using namespace std;
+using namespace libIRDB;
+
+class IntegerTransform64 : public Transform
+{
+	public:
+		IntegerTransform64(VariantID_t *, FileIR_t*, std::map<VirtualOffset, MEDS_InstructionCheckAnnotation> *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_warnings); 
+
+		int execute();
+
+		void setSaturatingArithmetic(bool p_satArithmetic) { m_policySaturatingArithmetic = p_satArithmetic; }
+		bool isSaturatingArithmetic() { return m_policySaturatingArithmetic; }
+		void setPathManipulationDetected(bool p_pathManip) { m_pathManipulationDetected = p_pathManip; }
+		bool isPathManipulationDetected() { return m_pathManipulationDetected; }
+		void setWarningsOnly(bool p_warn) { m_policyWarningsOnly = p_warn; }
+		bool isWarningsOnly() { return m_policyWarningsOnly; }
+		void logStats();
+
+		bool isBlacklisted(Function_t *func);
+
+		std::map<VirtualOffset, MEDS_InstructionCheckAnnotation>* getAnnotations() { return m_annotations; }
+
+	protected:
+		void handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy);
+		void addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy);
+		void logMessage(const std::string &p_method, const std::string &p_msg);
+		void logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation&, const std::string &p_msg);
+
+	private:
+		std::map<VirtualOffset, MEDS_InstructionCheckAnnotation> *m_annotations;
+		std::set<VirtualOffset>*  m_benignFalsePositives;
+		bool                      m_policySaturatingArithmetic;
+		bool                      m_policyWarningsOnly;
+		bool                      m_pathManipulationDetected;
+
+		// statistics
+		unsigned m_numAnnotations; 
+		unsigned m_numIdioms; 
+		unsigned m_numBlacklisted; 
+		unsigned m_numBenign; 
+		unsigned m_numOverflows; 
+		unsigned m_numUnderflows; 
+		unsigned m_numTruncations; 
+		unsigned m_numSignedness; 
+		unsigned m_numOverflowsSkipped; 
+		unsigned m_numUnderflowsSkipped; 
+		unsigned m_numTruncationsSkipped; 
+		unsigned m_numSignednessSkipped; 
+		unsigned m_numFP; 
+};
+
+
+} // end namespace
+
+#endif
diff --git a/libtransform/include/transform.hpp b/libtransform/include/transform.hpp
index ee637175ee6683a3543023015c20dbd27470ca62..25a9c3319f98244691acc19881d69c2927911ed9 100644
--- a/libtransform/include/transform.hpp
+++ b/libtransform/include/transform.hpp
@@ -49,6 +49,7 @@ class Transform {
 		void addJnz(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target);
 		void addJae(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target);
 		void addNot(Instruction_t *p_instr, Register::RegisterName, Instruction_t *p_fallThrough);
+		void addHlt(Instruction_t *p_instr, Instruction_t *p_fallThrough);
 
 		void addAddRegisters(Instruction_t *p_instr, Register::RegisterName p_regTgt, Register::RegisterName p_regSrc, Instruction_t *p_fallThrough);
 		void addAddRegisterConstant(Instruction_t *p_instr, Register::RegisterName p_regTgt, int p_constantValue, Instruction_t *p_fallThrough);
diff --git a/libtransform/src/Makefile b/libtransform/src/Makefile
index 42a516afd53b771ba3a308d48a6ae45716a5dc56..49c3c4e7fe2598c572d7a133e2542dc4fee2db4e 100644
--- a/libtransform/src/Makefile
+++ b/libtransform/src/Makefile
@@ -1,6 +1,6 @@
 LIB=../lib/libtransform.a
 
-OBJS=transform.o integertransform.o leapattern.o
+OBJS=transform.o integertransform.o leapattern.o integertransform64.o
 
 all: $(OBJS)
 
diff --git a/libtransform/src/integertransform64.cpp b/libtransform/src/integertransform64.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44e6aca2e6701d8dc1a359bb59421e97eb25c44f
--- /dev/null
+++ b/libtransform/src/integertransform64.cpp
@@ -0,0 +1,210 @@
+#include <assert.h>
+
+#include "integertransform64.hpp"
+
+using namespace libTransform;
+
+IntegerTransform64::IntegerTransform64(VariantID_t *p_variantID, FileIR_t *p_fileIR, std::map<VirtualOffset, MEDS_InstructionCheckAnnotation> *p_annotations, set<std::string> *p_filteredFunctions, set<VirtualOffset> *p_benignFalsePositives) : Transform(p_variantID, p_fileIR, p_annotations, p_filteredFunctions) 
+{
+	m_benignFalsePositives = p_benignFalsePositives;
+	m_policySaturatingArithmetic = false;
+	m_policyWarningsOnly = false;
+	m_pathManipulationDetected = false;
+	m_annotations = p_annotations;              
+
+	m_numAnnotations = 0;
+	m_numIdioms = 0;
+	m_numBlacklisted = 0;
+	m_numBenign = 0;
+	m_numOverflows = 0;
+	m_numUnderflows = 0;
+	m_numTruncations = 0;
+	m_numSignedness = 0;
+	m_numFP = 0;
+	m_numOverflowsSkipped = 0;
+	m_numUnderflowsSkipped = 0;
+	m_numTruncationsSkipped = 0;
+	m_numSignednessSkipped = 0;
+}
+
+// iterate through all functions
+// filter those functions that should be ignored
+//    iterate through all instructions in function
+//    if MEDS annotation says to instrument
+//       add instrumentation
+int IntegerTransform64::execute()
+{
+	if (isWarningsOnly())
+		logMessage(__func__, "warnings only mode");
+
+	for(
+	  set<Function_t*>::const_iterator itf=getFileIR()->GetFunctions().begin();
+	  itf!=getFileIR()->GetFunctions().end();
+	  ++itf
+	  )
+	{
+		Function_t* func=*itf;
+
+		if (getFilteredFunctions()->find(func->GetName()) != getFilteredFunctions()->end())
+		{
+			logMessage(__func__, "filter out: " + func->GetName());
+			continue;
+		}
+
+		if (isBlacklisted(func))
+		{
+			logMessage(__func__, "blacklisted: " + func->GetName());
+			m_numBlacklisted++;
+			continue;
+		}
+
+		logMessage(__func__, "processing fn: " + func->GetName());
+
+		for(
+		  set<Instruction_t*>::const_iterator it=func->GetInstructions().begin();
+		  it!=func->GetInstructions().end();
+		  ++it)
+		{
+			Instruction_t* insn=*it;
+
+			if (insn && insn->GetAddress())
+			{
+				int policy = POLICY_EXIT; //  default for now is exit -- no callback handlers yet
+				virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset();
+				if (irdb_vo == 0) continue;
+
+				VirtualOffset vo(irdb_vo);
+
+				MEDS_InstructionCheckAnnotation annotation = (*getAnnotations())[vo];
+				if (!annotation.isValid()) 
+					continue;
+
+				logMessage(__func__, annotation, "-- instruction: " + insn->getDisassembly());
+				m_numAnnotations++;
+
+				if (annotation.isIdiom())
+				{
+					logMessage(__func__, "skip IDIOM");
+					m_numIdioms++;
+					continue;
+				}
+
+				if (!insn->GetFallthrough())
+				{
+					logMessage(__func__, "Warning: no fall through for instruction -- skipping");
+					continue;
+				}
+
+				if (annotation.isOverflow())
+				{
+					// nb: safe with respect to esp (except for lea)
+					handleOverflowCheck(insn, annotation, policy);
+				}
+			}
+		} // end iterate over all instructions in a function
+	} // end iterate over all functions
+
+	return 0;
+}
+
+void IntegerTransform64::handleOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy)
+{
+	if (isMultiplyInstruction(p_instruction) || (p_annotation.isOverflow() && !p_annotation.isUnknownSign()))
+	{
+		// handle signed/unsigned add/sub overflows (non lea)
+		addOverflowCheck(p_instruction, p_annotation, p_policy);
+	}
+	else
+	{
+		m_numOverflowsSkipped++;
+		logMessage(__func__, "OVERFLOW type not yet handled");
+	}
+}
+
+//
+//		mul a, b                 ; <instruction to instrument>
+//		jno <OrigNext>
+//      	halt
+// OrigNext:	<nextInstruction>
+//
+void IntegerTransform64::addOverflowCheck(Instruction_t *p_instruction, const MEDS_InstructionCheckAnnotation& p_annotation, int p_policy)
+{
+	Instruction_t* jncond_i = NULL;
+	Instruction_t* hlt_i = NULL;
+
+	assert(getFileIR() && p_instruction && p_instruction->GetFallthrough());
+
+	cerr << __func__ <<  ": instr: " << p_instruction->getDisassembly() << " address: " << std::hex << p_instruction->GetAddress() << " annotation: " << p_annotation.toString() << " policy: " << p_policy << endl;
+
+	jncond_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction());
+	hlt_i = allocateNewInstruction(p_instruction->GetAddress()->GetFileID(), p_instruction->GetFunction());
+
+	Instruction_t* next_i = p_instruction->GetFallthrough();
+	p_instruction->SetFallthrough(jncond_i); 
+
+	if (p_annotation.isUnsigned())
+	{
+		addJnc(jncond_i, hlt_i, next_i);
+	}
+	else
+	{
+		addJno(jncond_i, hlt_i, next_i);
+	}
+	addHlt(hlt_i, next_i);
+
+	if (p_annotation.isUnderflow())
+		m_numUnderflows++;
+	else
+		m_numOverflows++;
+}
+
+// @todo: move to base class
+void IntegerTransform64::logMessage(const std::string &p_method, const std::string &p_msg)
+{
+	std::cerr << p_method << ": " << p_msg << std::endl;
+}
+
+// @todo: move to base class
+void IntegerTransform64::logMessage(const std::string &p_method, const MEDS_InstructionCheckAnnotation& p_annotation, const std::string &p_msg)
+{
+	logMessage(p_method, p_msg + " annotation: " + p_annotation.toString());
+}
+
+void IntegerTransform64::logStats()
+{
+	std::string fileURL = getFileIR()->GetFile()->GetURL();	
+
+	std::cerr << "# ATTRIBUTE file_name=" << fileURL << std::endl;
+	std::cerr << "# ATTRIBUTE num_annotations_processed=" << dec << m_numAnnotations << std::endl;
+	std::cerr << "# ATTRIBUTE num_idioms=" << m_numIdioms << std::endl;
+	std::cerr << "# ATTRIBUTE num_blacklisted=" << m_numBlacklisted << std::endl;
+	std::cerr << "# ATTRIBUTE num_benign=" << m_numBenign << std::endl;
+	std::cerr << "# ATTRIBUTE num_overflows_instrumented=" << m_numOverflows << std::endl;
+	std::cerr << "# ATTRIBUTE num_overflows_skipped=" << m_numOverflowsSkipped << std::endl;
+	std::cerr << "# ATTRIBUTE num_underflows_instrumented=" << m_numUnderflows << std::endl;
+	std::cerr << "# ATTRIBUTE num_underflows_skipped=" << m_numUnderflowsSkipped << std::endl;
+	std::cerr << "# ATTRIBUTE num_truncations_instrumented=" << m_numTruncations << std::endl;
+	std::cerr << "# ATTRIBUTE num_truncations_skipped=" << m_numTruncationsSkipped << std::endl;
+	std::cerr << "# ATTRIBUTE num_signedness_instrumented=" << m_numSignedness << std::endl;
+	std::cerr << "# ATTRIBUTE num_signedness_skipped=" << m_numSignednessSkipped << std::endl;
+	std::cerr << "# ATTRIBUTE num_floating_point=" << m_numFP << std::endl;
+}
+
+// functions known to be problematic b/c of bitwise manipulation
+bool IntegerTransform64::isBlacklisted(Function_t *func)
+{
+	if (!func) return false;
+	const char *funcName = func->GetName().c_str();
+	return (strcasestr(funcName, "hash") ||
+		strcasestr(funcName, "compress") ||
+		strcasestr(funcName, "encode") ||
+		strcasestr(funcName, "decode") ||
+		strcasestr(funcName, "crypt") ||
+		strcasestr(funcName, "yyparse") ||
+		strcasestr(funcName, "yyerror") ||
+		strcasestr(funcName, "yydestruct") ||
+		strcasestr(funcName, "yyrestart") ||
+		strcasestr(funcName, "yylex") ||
+		strcasestr(funcName, "yy_"));
+}
+
diff --git a/libtransform/src/transform.cpp b/libtransform/src/transform.cpp
index f00cda0de4df59b6592b6e1a1b2eca782fda7407..08e80ee14e556875072147d76bc21ea65998a018 100644
--- a/libtransform/src/transform.cpp
+++ b/libtransform/src/transform.cpp
@@ -872,18 +872,6 @@ void Transform::addJo(Instruction_t *p_instr, Instruction_t *p_fallThrough, Inst
 
 	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
 }
-
-// jno - jump not overflow
-void Transform::addJno(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target)
-{
-	string dataBits;
-	dataBits.resize(2);
-	dataBits[0] = 0x71;
-	dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later
-
-	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
-}
-
 // jc - jump carry
 void Transform::addJc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target)
 {
@@ -895,17 +883,6 @@ void Transform::addJc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Inst
 	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
 }
 
-// jnc - jump not carry
-void Transform::addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target)
-{
-	string dataBits;
-	dataBits.resize(2);
-	dataBits[0] = 0x73;
-	dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later
-
-	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
-}
-
 // not <reg> -- negate register
 void Transform::addNot(Instruction_t *p_instr, Register::RegisterName p_reg, Instruction_t *p_fallThrough)
 {
@@ -1173,3 +1150,48 @@ void Transform::addAndRegister32Mask(Instruction_t *p_instr, Register::RegisterN
 	p_instr->SetComment("Saturating arithmetic by masking");
 }
 
+// known to be used on x86-64
+
+// hlt
+void Transform::addHlt(Instruction_t *p_instr, Instruction_t *p_fallThrough)
+{
+	string assembly("hlt");
+	m_fileIR->RegisterAssembly(p_instr, assembly);
+	p_instr->SetFallthrough(p_fallThrough);
+}
+
+
+// jno - jump not overflow
+void Transform::addJno(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target)
+{
+#ifdef OLD_WAY
+	string dataBits;
+	dataBits.resize(2);
+	dataBits[0] = 0x71;
+	dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later
+
+	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
+#endif
+
+	string assembly("jno 0x22");
+	m_fileIR->RegisterAssembly(p_instr, assembly);
+	p_instr->SetFallthrough(p_fallThrough);
+	p_instr->SetTarget(p_target);
+}
+
+// jnc - jump not carry
+void Transform::addJnc(Instruction_t *p_instr, Instruction_t *p_fallThrough, Instruction_t *p_target)
+{
+#ifdef OLD_WAY
+	string dataBits;
+	dataBits.resize(2);
+	dataBits[0] = 0x73;
+	dataBits[1] = 0x00; // value doesn't matter -- we will fill it in later
+
+	addInstruction(p_instr, dataBits, p_fallThrough, p_target);
+#endif
+	string assembly("jnc 0x22");
+	m_fileIR->RegisterAssembly(p_instr, assembly);
+	p_instr->SetFallthrough(p_fallThrough);
+	p_instr->SetTarget(p_target);
+}
diff --git a/libtransform/tests/Makefile b/libtransform/tests/Makefile
index a5511e6728545969610d30561061db6a2b655a95..0d0c8a997e36f25963f15db46c11ac8404b0cf2d 100644
--- a/libtransform/tests/Makefile
+++ b/libtransform/tests/Makefile
@@ -8,7 +8,7 @@ LD=DO_NOT_USE
 #exes=dumbledore_cmd.exe test1.exe
 #exes=overflow1.exe #overflow2.exe
 #exes=dumbledore_cmd.exe
-exes=integerbug.exe
+exes=unsigned_mul.exe signed_add.exe
 
 
 all: env_check  ${exes}
@@ -20,7 +20,7 @@ all: env_check  ${exes}
 #	gcc -g $< -o $@ 
 	gcc $< -o $@ 
 #	${PEASOUP_HOME}/tools/ps_analyze.sh  $@ $@.peasoup 
-	${PEASOUP_HOME}/tools/ps_analyze.sh  $@ $@.peasoup --step ilr=off --step concolic=off --step p1transform=off --step isr=off
+	${PEASOUP_HOME}/tools/ps_analyze64.sh  $@ $@.peasoup --step ilr=off --step concolic=off --step p1transform=off --step isr=off
 
 .c.o:
 #	gcc -O2 -c $< 
diff --git a/libtransform/tests/signed_add.c b/libtransform/tests/signed_add.c
index da3e4adb333ac93a5be81dc7a584d29195f37495..c74cd0afdf2e52ff75efade4165007e280195609 100644
--- a/libtransform/tests/signed_add.c
+++ b/libtransform/tests/signed_add.c
@@ -1,12 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
 int main(int argc, char **argv)
 {
-  int a = atoi(argv[1]);
-  int b = atoi(argv[2]);
-  volatile int result;
+  int64_t a = atol(argv[1]);
+  int64_t b = atol(argv[2]);
+  volatile int64_t result;
   
-  printf("a = %d; b = %d\n", a, b);
+  printf("a = %ld; b = %ld\n", a, b);
 
   result = 1 + a + b;
 
-  printf("1 + a=%d + b=%d = %d\n", a, b, result);
+  printf("1 + a=%ld + b=%ld = %ld\n", a, b, result);
+
+  return 0;
 }
diff --git a/libtransform/tests/unsigned_mul.c b/libtransform/tests/unsigned_mul.c
index c9d30a68ee1469d30ab69f6474d1442a1e45fb23..0263f28b4074a99d017b0643f25cac760d3a8b2f 100644
--- a/libtransform/tests/unsigned_mul.c
+++ b/libtransform/tests/unsigned_mul.c
@@ -15,4 +15,6 @@ int main(int argc, char **argv)
 
   d = a * b;
   printf("%u\n", d);
+
+  return 0;
 }
diff --git a/tools/transforms/integertransformdriver.cpp b/tools/transforms/integertransformdriver.cpp
index 88bc03c54e9875334f082b7aed086d68c9a043d7..4d52823e6ce9d519dd2bb00506f29d5ffe2fce86 100644
--- a/tools/transforms/integertransformdriver.cpp
+++ b/tools/transforms/integertransformdriver.cpp
@@ -5,6 +5,7 @@
 
 #include "MEDS_AnnotationParser.hpp"
 #include "transformutils.h"
+#include "integertransform64.hpp"
 #include "integertransform.hpp"
 
 // current convention
@@ -106,7 +107,7 @@ main(int argc, char **argv)
 	assert(pidp->IsRegistered()==true);
 
 	bool one_success = false;
-    for(set<File_t*>::iterator it=pidp->GetFiles().begin();
+	for(set<File_t*>::iterator it=pidp->GetFiles().begin();
 	    it!=pidp->GetFiles().end();
 		++it)
 	{
@@ -148,18 +149,38 @@ main(int argc, char **argv)
 			std::map<VirtualOffset, MEDS_InstructionCheckAnnotation> annotations = annotationParser.getAnnotations();
 
 			// do the transformation
-			libTransform::IntegerTransform integerTransform(pidp, firp, &annotations, &filteredFunctions, &warnings);
-			integerTransform.setSaturatingArithmetic(isSaturatingArithmeticOn(argc, argv));
-			integerTransform.setPathManipulationDetected(isPathManipDetected(argc, argv));
-			integerTransform.setWarningsOnly(isWarningsOnly(argc, argv));
 
-			int exitcode = integerTransform.execute();
-			if (exitcode == 0)
+			if(firp->GetArchitectureBitWidth()==64)
 			{
-				one_success = true;
-				firp->WriteToDB();
-				integerTransform.logStats();
-				delete firp;
+				libTransform::IntegerTransform64 integerTransform64(pidp, firp, &annotations, &filteredFunctions, &warnings);
+				integerTransform64.setSaturatingArithmetic(isSaturatingArithmeticOn(argc, argv));
+				integerTransform64.setPathManipulationDetected(isPathManipDetected(argc, argv));
+				integerTransform64.setWarningsOnly(isWarningsOnly(argc, argv));
+
+				int exitcode = integerTransform64.execute();
+				if (exitcode == 0)
+				{
+					one_success = true;
+					firp->WriteToDB();
+					integerTransform64.logStats();
+					delete firp;
+				}
+			}
+			else if(firp->GetArchitectureBitWidth()==32)
+			{
+				libTransform::IntegerTransform integerTransform(pidp, firp, &annotations, &filteredFunctions, &warnings);
+				integerTransform.setSaturatingArithmetic(isSaturatingArithmeticOn(argc, argv));
+				integerTransform.setPathManipulationDetected(isPathManipDetected(argc, argv));
+				integerTransform.setWarningsOnly(isWarningsOnly(argc, argv));
+
+				int exitcode = integerTransform.execute();
+				if (exitcode == 0)
+				{
+					one_success = true;
+					firp->WriteToDB();
+					integerTransform.logStats();
+					delete firp;
+				}
 			}
 		}
 		catch (DatabaseError_t pnide)