aboutsummaryrefslogtreecommitdiffhomepage
path: root/interp
diff options
context:
space:
mode:
Diffstat (limited to 'interp')
-rw-r--r--interp/interpreter.go48
-rw-r--r--interp/memory.go16
2 files changed, 20 insertions, 44 deletions
diff --git a/interp/interpreter.go b/interp/interpreter.go
index 7c58a5d20..46aa9d1f4 100644
--- a/interp/interpreter.go
+++ b/interp/interpreter.go
@@ -346,16 +346,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
dstObj.buffer = dstBuf
mem.put(dst.index(), dstObj)
}
- switch inst.llvmInst.Type().IntTypeWidth() {
- case 16:
- locals[inst.localIndex] = literalValue{uint16(n)}
- case 32:
- locals[inst.localIndex] = literalValue{uint32(n)}
- case 64:
- locals[inst.localIndex] = literalValue{uint64(n)}
- default:
- panic("unknown integer type width")
- }
+ locals[inst.localIndex] = makeLiteralInt(n, inst.llvmInst.Type().IntTypeWidth())
case strings.HasPrefix(callFn.name, "llvm.memcpy.p0") || strings.HasPrefix(callFn.name, "llvm.memmove.p0"):
// Copy a block of memory from one pointer to another.
dst, err := operands[1].asPointer(r)
@@ -647,16 +638,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
}
// GEP on fixed pointer value (for example, memory-mapped I/O).
ptrValue := operands[0].Uint() + offset
- switch operands[0].len(r) {
- case 8:
- locals[inst.localIndex] = literalValue{uint64(ptrValue)}
- case 4:
- locals[inst.localIndex] = literalValue{uint32(ptrValue)}
- case 2:
- locals[inst.localIndex] = literalValue{uint16(ptrValue)}
- default:
- panic("pointer operand is not of a known pointer size")
- }
+ locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8))
continue
}
ptr = ptr.addOffset(int64(offset))
@@ -810,18 +792,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
default:
panic("unreachable")
}
- switch lhs.len(r) {
- case 8:
- locals[inst.localIndex] = literalValue{result}
- case 4:
- locals[inst.localIndex] = literalValue{uint32(result)}
- case 2:
- locals[inst.localIndex] = literalValue{uint16(result)}
- case 1:
- locals[inst.localIndex] = literalValue{uint8(result)}
- default:
- panic("unknown integer size")
- }
+ locals[inst.localIndex] = makeLiteralInt(result, int(lhs.len(r)*8))
if r.debug {
fmt.Fprintln(os.Stderr, indent+instructionNameMap[inst.opcode]+":", lhs, rhs, "->", result)
}
@@ -843,18 +814,7 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if r.debug {
fmt.Fprintln(os.Stderr, indent+instructionNameMap[inst.opcode]+":", value, bitwidth)
}
- switch bitwidth {
- case 64:
- locals[inst.localIndex] = literalValue{value}
- case 32:
- locals[inst.localIndex] = literalValue{uint32(value)}
- case 16:
- locals[inst.localIndex] = literalValue{uint16(value)}
- case 8:
- locals[inst.localIndex] = literalValue{uint8(value)}
- default:
- panic("unknown integer size in sext/zext/trunc")
- }
+ locals[inst.localIndex] = makeLiteralInt(value, int(bitwidth))
case llvm.SIToFP, llvm.UIToFP:
var value float64
switch inst.opcode {
diff --git a/interp/memory.go b/interp/memory.go
index f96387062..2065bcdf5 100644
--- a/interp/memory.go
+++ b/interp/memory.go
@@ -373,6 +373,22 @@ type literalValue struct {
value interface{}
}
+// Make a literalValue given the number of bits.
+func makeLiteralInt(value uint64, bits int) literalValue {
+ switch bits {
+ case 64:
+ return literalValue{value}
+ case 32:
+ return literalValue{uint32(value)}
+ case 16:
+ return literalValue{uint16(value)}
+ case 8:
+ return literalValue{uint8(value)}
+ default:
+ panic("unknown integer size")
+ }
+}
+
func (v literalValue) len(r *runner) uint32 {
switch v.value.(type) {
case uint64: