summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <tstellar@gmail.com>2011-01-04 21:52:12 -0800
committerTom Stellard <tstellar@gmail.com>2011-01-04 21:52:12 -0800
commit4a2a6eb61e9bdcefeaf73ab16c61acafd9c85f71 (patch)
treed48ebebd1057b34393e1b022ee1d78262de8f741
parente5ab0c159565b9f012ff00f3b5471b02bd7ee4eb (diff)
Add rcp_instruction
-rw-r--r--evaluator.cpp39
-rw-r--r--evaluator.h9
-rw-r--r--instruction.cpp4
-rw-r--r--instruction.h5
4 files changed, 57 insertions, 0 deletions
diff --git a/evaluator.cpp b/evaluator.cpp
index c61b116..f554a0a 100644
--- a/evaluator.cpp
+++ b/evaluator.cpp
@@ -1,5 +1,6 @@
#include <math.h>
+#include <stdio.h>
#include "evaluator.h"
#include "value.h"
@@ -167,3 +168,41 @@ sat_evaluator::evaluate(
}
return new float_value(val);
}
+
+rcp_evaluator::rcp_evaluator() :
+ evaluator("RCP")
+ { }
+
+value *
+rcp_evaluator::evaluate(
+ float_value * l,
+ float_value * r)
+{
+ float val;
+ int float_type;
+ fprintf(stderr, "RCP\n");
+ if (!l || !l->m_has_value) {
+ return default_evaluate(l, r);
+ }
+ /* XXX: This should be configurable via virtual functions. */
+ float_type = fpclassify(l->m_value);
+ switch(float_type) {
+ case FP_NAN:
+ val = NAN;
+ break;
+ case FP_INFINITE:
+ val = 0.0f;
+ break;
+ default:
+ /* XXX: fpclassify should be used to test for zero once I
+ * figure out if FP_ZERO is portable. */
+ if (l->m_value == 0.0f) {
+ val = INFINITY;
+ } else {
+ val = 1.0f / l->m_value;
+ }
+ break;
+ }
+ fprintf(stderr, "val=%f\n", val);
+ return new float_value(val);
+}
diff --git a/evaluator.h b/evaluator.h
index cd90765..3786950 100644
--- a/evaluator.h
+++ b/evaluator.h
@@ -72,4 +72,13 @@ public:
float_value * l,
float_value * r);
};
+
+class rcp_evaluator : public evaluator {
+public:
+ rcp_evaluator();
+ value * evaluate(
+ float_value * l,
+ float_value * r);
+};
+
#endif //EVALUATOR_H_
diff --git a/instruction.cpp b/instruction.cpp
index 5787c21..0b703d0 100644
--- a/instruction.cpp
+++ b/instruction.cpp
@@ -127,3 +127,7 @@ sub_instruction::sub_instruction(std::vector<register_address> dst) :
sat_instruction::sat_instruction(std::vector<register_address> dst) :
instruction("SAT", new sat_evaluator(), dst, 1)
{ }
+
+rcp_instruction::rcp_instruction(std::vector<register_address> dst) :
+ instruction("RCP", new rcp_evaluator(), dst, 1)
+ { }
diff --git a/instruction.h b/instruction.h
index cded5ca..4e88aaa 100644
--- a/instruction.h
+++ b/instruction.h
@@ -78,4 +78,9 @@ public:
sat_instruction(std::vector<register_address> dst);
};
+class rcp_instruction : public instruction {
+public:
+ rcp_instruction(std::vector<register_address> dst);
+};
+
#endif //INSTRUCTION_H_