summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2014-11-19 14:24:41 -0500
committerAustin Clements <austin@google.com>2014-11-19 14:24:41 -0500
commit9a7a6cdead943e05114d54daf86b075397a32029 (patch)
treef604bb2ae79f95e49b7367cb2e52843f850df850
parentc2f443bf7b05a302c662c52a77dc8111471ff65c (diff)
downloadgo-9a7a6cdead943e05114d54daf86b075397a32029.tar.gz
[dev.cc] runtime: decode power64 branch instructions the way the CPU does
Previously, this used the top 8 bits of an instruction as a sort-of opcode and ignored the top two bits of the relative PC. This worked because these jumps are always negative and never big enough for the top two bits of the relative PC (also the bottom 2 bits of the sort-of opcode) to be anything other than 0b11, but the code is confusing because it doesn't match the actual structure of the instruction. Instead, use the real 6 bit opcode and use all 24 bits of relative PC. LGTM=rsc R=rsc, dave CC=golang-codereviews https://codereview.appspot.com/179960043
-rw-r--r--src/runtime/sys_power64x.go6
1 files changed, 3 insertions, 3 deletions
diff --git a/src/runtime/sys_power64x.go b/src/runtime/sys_power64x.go
index f32d1a44f..90ebde7b4 100644
--- a/src/runtime/sys_power64x.go
+++ b/src/runtime/sys_power64x.go
@@ -26,9 +26,9 @@ func rewindmorestack(buf *gobuf) {
var inst uint32
if buf.pc&3 == 0 && buf.pc != 0 {
inst = *(*uint32)(unsafe.Pointer(buf.pc))
- if inst>>24 == 0x4b && inst&3 == 0 {
- //print("runtime: rewind pc=", hex(buf.pc), " to pc=", hex(uintptr(buf.pc + int32(inst<<8)>>8)), "\n");
- buf.pc += uintptr(int32(inst<<8) >> 8)
+ if inst>>26 == 18 && inst&3 == 0 {
+ //print("runtime: rewind pc=", hex(buf.pc), " to pc=", hex(uintptr(buf.pc + int32(inst<<6)>>6)), "\n");
+ buf.pc += uintptr(int32(inst<<6) >> 6)
return
}
}