Tue, 24 Oct 2017 14:04:09 +0800
[Assembler] Complex address modes support for Assembler::lea(Register rt, Address src), Assembler::sd(Register rt, Address dst) and Assembler::sw(Register rt, Address dst)
aoqi@1 | 1 | /* |
aoqi@1 | 2 | * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
aoqi@1 | 3 | * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved. |
aoqi@1 | 4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@1 | 5 | * |
aoqi@1 | 6 | * This code is free software; you can redistribute it and/or modify it |
aoqi@1 | 7 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@1 | 8 | * published by the Free Software Foundation. |
aoqi@1 | 9 | * |
aoqi@1 | 10 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@1 | 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@1 | 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@1 | 13 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@1 | 14 | * accompanied this code). |
aoqi@1 | 15 | * |
aoqi@1 | 16 | * You should have received a copy of the GNU General Public License version |
aoqi@1 | 17 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@1 | 18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@1 | 19 | * |
aoqi@1 | 20 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@1 | 21 | * or visit www.oracle.com if you need additional information or have any |
aoqi@1 | 22 | * questions. |
aoqi@1 | 23 | * |
aoqi@1 | 24 | */ |
aoqi@1 | 25 | |
aoqi@1 | 26 | #include "precompiled.hpp" |
aoqi@1 | 27 | #include "asm/assembler.hpp" |
aoqi@1 | 28 | #include "asm/assembler.inline.hpp" |
aoqi@1 | 29 | #include "gc_interface/collectedHeap.inline.hpp" |
aoqi@1 | 30 | #include "interpreter/interpreter.hpp" |
aoqi@1 | 31 | #include "memory/cardTableModRefBS.hpp" |
aoqi@1 | 32 | #include "memory/resourceArea.hpp" |
aoqi@1 | 33 | #include "prims/methodHandles.hpp" |
aoqi@1 | 34 | #include "runtime/biasedLocking.hpp" |
aoqi@1 | 35 | #include "runtime/interfaceSupport.hpp" |
aoqi@1 | 36 | #include "runtime/objectMonitor.hpp" |
aoqi@1 | 37 | #include "runtime/os.hpp" |
aoqi@1 | 38 | #include "runtime/sharedRuntime.hpp" |
aoqi@1 | 39 | #include "runtime/stubRoutines.hpp" |
aoqi@6880 | 40 | #if INCLUDE_ALL_GCS |
aoqi@1 | 41 | #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
aoqi@1 | 42 | #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" |
aoqi@1 | 43 | #include "gc_implementation/g1/heapRegion.hpp" |
aoqi@6880 | 44 | #endif // INCLUDE_ALL_GCS |
aoqi@6880 | 45 | |
aoqi@1 | 46 | #ifdef PRODUCT |
aoqi@1 | 47 | #define BLOCK_COMMENT(str) /* nothing */ |
aoqi@1 | 48 | #define STOP(error) stop(error) |
aoqi@1 | 49 | #else |
aoqi@1 | 50 | #define BLOCK_COMMENT(str) block_comment(str) |
aoqi@1 | 51 | #define STOP(error) block_comment(error); stop(error) |
aoqi@1 | 52 | #endif |
aoqi@1 | 53 | |
aoqi@1 | 54 | #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") |
aoqi@1 | 55 | |
aoqi@1 | 56 | // Implementation of AddressLiteral |
aoqi@1 | 57 | |
aoqi@1 | 58 | AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) { |
aoqi@1 | 59 | _is_lval = false; |
aoqi@1 | 60 | _target = target; |
aoqi@1 | 61 | _rspec = rspec_from_rtype(rtype, target); |
aoqi@1 | 62 | } |
aoqi@1 | 63 | |
aoqi@1 | 64 | // Implementation of Address |
aoqi@1 | 65 | |
aoqi@1 | 66 | |
aoqi@1 | 67 | Address Address::make_array(ArrayAddress adr) { |
aoqi@1 | 68 | AddressLiteral base = adr.base(); |
aoqi@1 | 69 | Address index = adr.index(); |
aoqi@1 | 70 | assert(index._disp == 0, "must not have disp"); // maybe it can? |
aoqi@1 | 71 | Address array(index._base, index._index, index._scale, (intptr_t) base.target()); |
aoqi@1 | 72 | array._rspec = base._rspec; |
aoqi@1 | 73 | return array; |
aoqi@1 | 74 | } |
aoqi@1 | 75 | |
aoqi@1 | 76 | // exceedingly dangerous constructor |
aoqi@1 | 77 | Address::Address(address loc, RelocationHolder spec) { |
aoqi@1 | 78 | _base = noreg; |
aoqi@1 | 79 | _index = noreg; |
aoqi@1 | 80 | _scale = no_scale; |
aoqi@1 | 81 | _disp = (intptr_t) loc; |
aoqi@1 | 82 | _rspec = spec; |
aoqi@1 | 83 | } |
aoqi@1 | 84 | |
aoqi@1 | 85 | |
aoqi@1 | 86 | // Implementation of Assembler |
aoqi@1 | 87 | const char *Assembler::ops_name[] = { |
aoqi@6880 | 88 | "special", "regimm", "j", "jal", "beq", "bne", "blez", "bgtz", |
aoqi@6880 | 89 | "addi", "addiu", "slti", "sltiu", "andi", "ori", "xori", "lui", |
aoqi@6880 | 90 | "cop0", "cop1", "cop2", "cop3", "beql", "bnel", "bleql", "bgtzl", |
aoqi@6880 | 91 | "daddi", "daddiu", "ldl", "ldr", "", "", "", "", |
aoqi@6880 | 92 | "lb", "lh", "lwl", "lw", "lbu", "lhu", "lwr", "lwu", |
aoqi@6880 | 93 | "sb", "sh", "swl", "sw", "sdl", "sdr", "swr", "cache", |
aoqi@6880 | 94 | "ll", "lwc1", "", "", "lld", "ldc1", "", "ld", |
aoqi@6880 | 95 | "sc", "swc1", "", "", "scd", "sdc1", "", "sd" |
aoqi@1 | 96 | }; |
aoqi@1 | 97 | |
aoqi@1 | 98 | const char* Assembler::special_name[] = { |
aoqi@6880 | 99 | "sll", "", "srl", "sra", "sllv", "", "srlv", "srav", |
aoqi@6880 | 100 | "jr", "jalr", "movz", "movn", "syscall", "break", "", "sync", |
aoqi@6880 | 101 | "mfhi", "mthi", "mflo", "mtlo", "dsll", "", "dsrl", "dsra", |
aoqi@6880 | 102 | "mult", "multu", "div", "divu", "dmult", "dmultu", "ddiv", "ddivu", |
aoqi@6880 | 103 | "add", "addu", "sub", "subu", "and", "or", "xor", "nor", |
aoqi@6880 | 104 | "", "", "slt", "sltu", "dadd", "daddu", "dsub", "dsubu", |
aoqi@6880 | 105 | "tge", "tgeu", "tlt", "tltu", "teq", "", "tne", "", |
aoqi@6880 | 106 | "dsll", "", "dsrl", "dsra", "dsll32", "", "dsrl32", "dsra32" |
aoqi@1 | 107 | }; |
aoqi@1 | 108 | |
aoqi@199 | 109 | const char* Assembler::cop1_name[] = { |
aoqi@339 | 110 | "add", "sub", "mul", "div", "sqrt", "abs", "mov", "neg", |
aoqi@339 | 111 | "round.l", "trunc.l", "ceil.l", "floor.l", "round.w", "trunc.w", "ceil.w", "floor.w", |
aoqi@339 | 112 | "", "", "", "", "", "", "", "", |
aoqi@339 | 113 | "", "", "", "", "", "", "", "", |
aoqi@339 | 114 | "", "", "", "", "", "", "", "", |
aoqi@339 | 115 | "", "", "", "", "", "", "", "", |
aoqi@339 | 116 | "c.f", "c.un", "c.eq", "c.ueq", "c.olt", "c.ult", "c.ole", "c.ule", |
aoqi@339 | 117 | "c.sf", "c.ngle", "c.seq", "c.ngl", "c.lt", "c.nge", "c.le", "c.ngt" |
aoqi@199 | 118 | }; |
aoqi@199 | 119 | |
aoqi@199 | 120 | const char* Assembler::cop1x_name[] = { |
aoqi@6880 | 121 | "lwxc1", "ldxc1", "", "", "", "luxc1", "", "", |
aoqi@6880 | 122 | "swxc1", "sdxc1", "", "", "", "suxc1", "", "prefx", |
aoqi@6880 | 123 | "", "", "", "", "", "", "alnv.ps", "", |
aoqi@6880 | 124 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 125 | "madd.s", "madd.d", "", "", "", "", "madd.ps", "", |
aoqi@6880 | 126 | "msub.s", "msub.d", "", "", "", "", "msub.ps", "", |
aoqi@6880 | 127 | "nmadd.s", "nmadd.d", "", "", "", "", "nmadd.ps", "", |
aoqi@6880 | 128 | "nmsub.s", "nmsub.d", "", "", "", "", "nmsub.ps", "" |
aoqi@199 | 129 | }; |
aoqi@199 | 130 | |
fujie@41 | 131 | const char* Assembler::special2_name[] = { |
aoqi@6880 | 132 | "madd", "", "mul", "", "msub", "", "", "", |
aoqi@6880 | 133 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 134 | "", "gsdmult", "", "", "gsdiv", "gsddiv", "", "", |
aoqi@6880 | 135 | "", "", "", "", "gsmod", "gsdmod", "", "", |
aoqi@6880 | 136 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 137 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 138 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 139 | "", "", "", "", "", "", "", "" |
fujie@41 | 140 | }; |
fujie@41 | 141 | |
aoqi@199 | 142 | const char* Assembler::special3_name[] = { |
aoqi@6880 | 143 | "ext", "", "", "", "ins", "dinsm", "dinsu", "dins", |
aoqi@6880 | 144 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 145 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 146 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 147 | "bshfl", "", "", "", "", "", "", "", |
aoqi@6880 | 148 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 149 | "", "", "", "", "", "", "", "", |
aoqi@6880 | 150 | "", "", "", "", "", "", "", "", |
aoqi@199 | 151 | }; |
aoqi@199 | 152 | |
aoqi@1 | 153 | const char* Assembler::regimm_name[] = { |
aoqi@6880 | 154 | "bltz", "bgez", "bltzl", "bgezl", "", "", "", "", |
aoqi@6880 | 155 | "tgei", "tgeiu", "tlti", "tltiu", "teqi", "", "tnei", "", |
aoqi@6880 | 156 | "bltzal", "bgezal", "bltzall", "bgezall" |
aoqi@1 | 157 | }; |
aoqi@6880 | 158 | |
fujie@44 | 159 | const char* Assembler::gs_ldc2_name[] = { |
aoqi@6880 | 160 | "gslbx", "gslhx", "gslwx", "gsldx", "", "", "gslwxc1", "gsldxc1" |
fujie@44 | 161 | }; |
fujie@44 | 162 | |
lifangyuan@125 | 163 | |
lifangyuan@125 | 164 | const char* Assembler::gs_lwc2_name[] = { |
jiangshaofeng@362 | 165 | "", "", "", "", "", "", "", "", |
jiangshaofeng@362 | 166 | "", "", "", "", "", "", "", "", |
jiangshaofeng@362 | 167 | "gslble", "gslbgt", "gslhle", "gslhgt", "gslwle", "gslwgt", "gsldle", "gsldgt", |
jiangshaofeng@362 | 168 | "", "", "", "gslwlec1", "gslwgtc1", "gsldlec1", "gsldgtc1", "",/*LWDIR, LWPTE, LDDIR and LDPTE have the same low 6 bits.*/ |
jiangshaofeng@362 | 169 | "gslq", "" |
lifangyuan@125 | 170 | }; |
lifangyuan@125 | 171 | |
fujie@65 | 172 | const char* Assembler::gs_sdc2_name[] = { |
aoqi@6880 | 173 | "gssbx", "gsshx", "gsswx", "gssdx", "", "", "gsswxc1", "gssdxc1" |
fujie@65 | 174 | }; |
fujie@65 | 175 | |
lifangyuan@125 | 176 | const char* Assembler::gs_swc2_name[] = { |
jiangshaofeng@362 | 177 | "", "", "", "", "", "", "", "", |
jiangshaofeng@362 | 178 | "", "", "", "", "", "", "", "", |
jiangshaofeng@362 | 179 | "gssble", "gssbgt", "gsshle", "gsshgt", "gsswle", "gsswgt", "gssdle", "gssdgt", |
jiangshaofeng@362 | 180 | "", "", "", "", "gsswlec1", "gsswgtc1", "gssdlec1", "gssdgtc1", |
jiangshaofeng@362 | 181 | "gssq", "" |
lifangyuan@125 | 182 | }; |
lifangyuan@125 | 183 | |
aoqi@6880 | 184 | //misleading name, print only branch/jump instruction |
aoqi@1 | 185 | void Assembler::print_instruction(int inst) { |
aoqi@6880 | 186 | const char *s; |
aoqi@6880 | 187 | switch( opcode(inst) ) { |
aoqi@6880 | 188 | default: |
aoqi@6880 | 189 | s = ops_name[opcode(inst)]; |
aoqi@6880 | 190 | break; |
aoqi@6880 | 191 | case special_op: |
aoqi@6880 | 192 | s = special_name[special(inst)]; |
aoqi@6880 | 193 | break; |
aoqi@6880 | 194 | case regimm_op: |
aoqi@6880 | 195 | s = special_name[rt(inst)]; |
aoqi@6880 | 196 | break; |
aoqi@1 | 197 | } |
aoqi@1 | 198 | |
aoqi@6880 | 199 | ::tty->print("%s", s); |
aoqi@1 | 200 | } |
aoqi@1 | 201 | |
fujie@293 | 202 | int Assembler::is_int_mask(int x) { |
fujie@293 | 203 | int xx = x; |
fujie@293 | 204 | int count = 0; |
fujie@293 | 205 | |
fujie@293 | 206 | while (x != 0) { |
fujie@293 | 207 | x &= (x - 1); |
fujie@293 | 208 | count++; |
fujie@293 | 209 | } |
fujie@293 | 210 | |
fujie@293 | 211 | if ((1<<count) == (xx+1)) { |
fujie@293 | 212 | return count; |
fujie@293 | 213 | } else { |
fujie@293 | 214 | return -1; |
fujie@293 | 215 | } |
fujie@293 | 216 | } |
fujie@293 | 217 | |
fujie@301 | 218 | int Assembler::is_jlong_mask(jlong x) { |
fujie@301 | 219 | jlong xx = x; |
fujie@301 | 220 | int count = 0; |
fujie@301 | 221 | |
fujie@301 | 222 | while (x != 0) { |
fujie@301 | 223 | x &= (x - 1); |
fujie@301 | 224 | count++; |
fujie@301 | 225 | } |
fujie@301 | 226 | |
fujie@301 | 227 | if ((1<<count) == (xx+1)) { |
fujie@301 | 228 | return count; |
fujie@301 | 229 | } else { |
fujie@301 | 230 | return -1; |
fujie@301 | 231 | } |
fujie@301 | 232 | } |
fujie@301 | 233 | |
aoqi@1 | 234 | //without check, maybe fixed |
aoqi@1 | 235 | int Assembler::patched_branch(int dest_pos, int inst, int inst_pos) { |
aoqi@6880 | 236 | int v = (dest_pos - inst_pos - 4)>>2; |
aoqi@6880 | 237 | switch(opcode(inst)) { |
aoqi@6880 | 238 | case j_op: |
aoqi@6880 | 239 | case jal_op: |
aoqi@6880 | 240 | assert(false, "should not use j/jal here"); |
aoqi@6880 | 241 | break; |
aoqi@6880 | 242 | default: |
aoqi@6880 | 243 | assert(is_simm16(v), "must be simm16"); |
aoqi@1 | 244 | #ifndef PRODUCT |
aoqi@6880 | 245 | if(!is_simm16(v)) |
aoqi@6880 | 246 | { |
aoqi@6880 | 247 | tty->print_cr("must be simm16"); |
aoqi@6880 | 248 | tty->print_cr("Inst: %lx", inst); |
aoqi@6880 | 249 | } |
aoqi@1 | 250 | #endif |
aoqi@1 | 251 | |
aoqi@6880 | 252 | v = low16(v); |
aoqi@6880 | 253 | inst &= 0xffff0000; |
aoqi@6880 | 254 | break; |
aoqi@6880 | 255 | } |
aoqi@6880 | 256 | |
aoqi@6880 | 257 | return inst | v; |
aoqi@1 | 258 | } |
aoqi@1 | 259 | |
aoqi@1 | 260 | int Assembler::branch_destination(int inst, int pos) { |
aoqi@6880 | 261 | int off; |
aoqi@6880 | 262 | |
aoqi@6880 | 263 | switch(opcode(inst)) { |
aoqi@6880 | 264 | case j_op: |
aoqi@6880 | 265 | case jal_op: |
aoqi@6880 | 266 | assert(false, "should not use j/jal here"); |
aoqi@6880 | 267 | break; |
aoqi@6880 | 268 | default: |
aoqi@6880 | 269 | off = expand(low16(inst), 15); |
aoqi@6880 | 270 | break; |
aoqi@6880 | 271 | } |
aoqi@6880 | 272 | |
aoqi@6880 | 273 | return off ? pos + 4 + (off<<2) : 0; |
aoqi@1 | 274 | } |
aoqi@1 | 275 | |
aoqi@1 | 276 | int AbstractAssembler::code_fill_byte() { |
aoqi@6880 | 277 | return 0x00; // illegal instruction 0x00000000 |
aoqi@1 | 278 | } |
aoqi@1 | 279 | |
aoqi@1 | 280 | // Now the Assembler instruction (identical for 32/64 bits) |
aoqi@1 | 281 | |
aoqi@1 | 282 | void Assembler::lb(Register rt, Address src) { |
aoqi@6880 | 283 | lb(rt, src.base(), src.disp()); |
aoqi@1 | 284 | } |
aoqi@1 | 285 | |
aoqi@1 | 286 | void Assembler::lbu(Register rt, Address src) { |
aoqi@6880 | 287 | lbu(rt, src.base(), src.disp()); |
aoqi@1 | 288 | } |
aoqi@1 | 289 | |
aoqi@1 | 290 | void Assembler::ld(Register rt, Address src){ |
aoqi@6880 | 291 | ld(rt, src.base(), src.disp()); |
aoqi@1 | 292 | } |
aoqi@1 | 293 | |
aoqi@1 | 294 | void Assembler::ldl(Register rt, Address src){ |
aoqi@6880 | 295 | ldl(rt, src.base(), src.disp()); |
aoqi@1 | 296 | } |
aoqi@1 | 297 | |
aoqi@1 | 298 | void Assembler::ldr(Register rt, Address src){ |
aoqi@6880 | 299 | ldr(rt, src.base(), src.disp()); |
aoqi@1 | 300 | } |
aoqi@1 | 301 | |
aoqi@1 | 302 | void Assembler::lh(Register rt, Address src){ |
aoqi@6880 | 303 | lh(rt, src.base(), src.disp()); |
aoqi@1 | 304 | } |
aoqi@1 | 305 | |
aoqi@1 | 306 | void Assembler::lhu(Register rt, Address src){ |
aoqi@6880 | 307 | lhu(rt, src.base(), src.disp()); |
aoqi@1 | 308 | } |
aoqi@1 | 309 | |
aoqi@1 | 310 | void Assembler::ll(Register rt, Address src){ |
aoqi@6880 | 311 | ll(rt, src.base(), src.disp()); |
aoqi@1 | 312 | } |
aoqi@1 | 313 | |
aoqi@1 | 314 | void Assembler::lld(Register rt, Address src){ |
aoqi@6880 | 315 | lld(rt, src.base(), src.disp()); |
aoqi@1 | 316 | } |
aoqi@1 | 317 | |
aoqi@1 | 318 | void Assembler::lw(Register rt, Address src){ |
aoqi@6880 | 319 | lw(rt, src.base(), src.disp()); |
aoqi@1 | 320 | } |
aoqi@1 | 321 | void Assembler::lea(Register rt, Address src) { |
fujie@8001 | 322 | Register dst = rt; |
fujie@8001 | 323 | Register base = src.base(); |
fujie@8001 | 324 | Register index = src.index(); |
fujie@8001 | 325 | |
fujie@8001 | 326 | int scale = src.scale(); |
fujie@8001 | 327 | int disp = src.disp(); |
fujie@8001 | 328 | |
fujie@8001 | 329 | if (index == noreg) { |
fujie@8001 | 330 | if (is_simm16(disp)) { |
fujie@8001 | 331 | daddiu(dst, base, disp); |
fujie@8001 | 332 | } else { |
fujie@8001 | 333 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 334 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 335 | daddu(dst, base, AT); |
fujie@8001 | 336 | } |
fujie@8001 | 337 | } else { |
fujie@8001 | 338 | if (scale == 0) { |
fujie@8001 | 339 | if (is_simm16(disp)) { |
fujie@8001 | 340 | daddu(AT, base, index); |
fujie@8001 | 341 | daddiu(dst, AT, disp); |
fujie@8001 | 342 | } else { |
fujie@8001 | 343 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 344 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 345 | daddu(AT, base, AT); |
fujie@8001 | 346 | daddu(dst, AT, index); |
fujie@8001 | 347 | } |
fujie@8001 | 348 | } else { |
fujie@8001 | 349 | if (is_simm16(disp)) { |
fujie@8001 | 350 | dsll(AT, index, scale); |
fujie@8001 | 351 | daddu(AT, AT, base); |
fujie@8001 | 352 | daddiu(dst, AT, disp); |
fujie@8001 | 353 | } else { |
fujie@8001 | 354 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 355 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 356 | daddu(AT, AT, base); |
fujie@8001 | 357 | dsll(dst, index, scale); |
fujie@8001 | 358 | daddu(dst, dst, AT); |
fujie@8001 | 359 | } |
fujie@8001 | 360 | } |
fujie@8001 | 361 | } |
aoqi@1 | 362 | } |
aoqi@1 | 363 | |
aoqi@1 | 364 | void Assembler::lwl(Register rt, Address src){ |
aoqi@6880 | 365 | lwl(rt, src.base(), src.disp()); |
aoqi@1 | 366 | } |
aoqi@1 | 367 | |
aoqi@1 | 368 | void Assembler::lwr(Register rt, Address src){ |
aoqi@6880 | 369 | lwr(rt, src.base(), src.disp()); |
aoqi@1 | 370 | } |
aoqi@1 | 371 | |
aoqi@1 | 372 | void Assembler::lwu(Register rt, Address src){ |
aoqi@6880 | 373 | lwu(rt, src.base(), src.disp()); |
aoqi@1 | 374 | } |
aoqi@1 | 375 | |
aoqi@1 | 376 | void Assembler::sb(Register rt, Address dst) { |
aoqi@6880 | 377 | sb(rt, dst.base(), dst.disp()); |
aoqi@1 | 378 | } |
aoqi@1 | 379 | |
aoqi@1 | 380 | void Assembler::sc(Register rt, Address dst) { |
aoqi@6880 | 381 | sc(rt, dst.base(), dst.disp()); |
aoqi@1 | 382 | } |
aoqi@1 | 383 | |
aoqi@1 | 384 | void Assembler::scd(Register rt, Address dst) { |
aoqi@6880 | 385 | scd(rt, dst.base(), dst.disp()); |
aoqi@1 | 386 | } |
aoqi@1 | 387 | |
aoqi@1 | 388 | void Assembler::sd(Register rt, Address dst) { |
fujie@8001 | 389 | Register src = rt; |
fujie@8001 | 390 | Register base = dst.base(); |
fujie@8001 | 391 | Register index = dst.index(); |
fujie@8001 | 392 | |
fujie@8001 | 393 | int scale = dst.scale(); |
fujie@8001 | 394 | int disp = dst.disp(); |
fujie@8001 | 395 | |
fujie@8001 | 396 | if(index != noreg) { |
fujie@8001 | 397 | if(is_simm16(disp)) { |
fujie@8001 | 398 | if( UseLoongsonISA && is_simm(disp, 8)) { |
fujie@8001 | 399 | if (scale == 0) { |
fujie@8001 | 400 | gssdx(src, base, index, disp); |
fujie@8001 | 401 | } else { |
fujie@8001 | 402 | dsll(AT, index, scale); |
fujie@8001 | 403 | gssdx(src, base, AT, disp); |
fujie@8001 | 404 | } |
fujie@8001 | 405 | } else { |
fujie@8001 | 406 | if (scale == 0) { |
fujie@8001 | 407 | daddu(AT, base, index); |
fujie@8001 | 408 | } else { |
fujie@8001 | 409 | dsll(AT, index, scale); |
fujie@8001 | 410 | daddu(AT, base, AT); |
fujie@8001 | 411 | } |
fujie@8001 | 412 | sd(src, AT, disp); |
fujie@8001 | 413 | } |
fujie@8001 | 414 | } else { |
fujie@8001 | 415 | if (scale == 0) { |
fujie@8001 | 416 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 417 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 418 | daddu(AT, AT, base); |
fujie@8001 | 419 | if(UseLoongsonISA) { |
fujie@8001 | 420 | gssdx(src, AT, index, 0); |
fujie@8001 | 421 | } else { |
fujie@8001 | 422 | daddu(AT, AT, index); |
fujie@8001 | 423 | sd(src, AT, 0); |
fujie@8001 | 424 | } |
fujie@8001 | 425 | } else { |
fujie@8001 | 426 | dsll(AT, index, scale); |
fujie@8001 | 427 | daddu(AT, base, AT); |
fujie@8001 | 428 | lui(T9, split_low(disp >> 16)); |
fujie@8001 | 429 | if (split_low(disp)) ori(T9, T9, split_low(disp)); |
fujie@8001 | 430 | if(UseLoongsonISA) { |
fujie@8001 | 431 | gssdx(src, AT, T9, 0); |
fujie@8001 | 432 | } else { |
fujie@8001 | 433 | daddu(AT, AT, T9); |
fujie@8001 | 434 | sd(src, AT, 0); |
fujie@8001 | 435 | } |
fujie@8001 | 436 | } |
fujie@8001 | 437 | } |
fujie@8001 | 438 | } else { |
fujie@8001 | 439 | if(is_simm16(disp)) { |
fujie@8001 | 440 | sd(src, base, disp); |
fujie@8001 | 441 | } else { |
fujie@8001 | 442 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 443 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 444 | |
fujie@8001 | 445 | if(UseLoongsonISA) { |
fujie@8001 | 446 | gssdx(src, base, AT, 0); |
fujie@8001 | 447 | } else { |
fujie@8001 | 448 | daddu(AT, base, AT); |
fujie@8001 | 449 | sd(src, AT, 0); |
fujie@8001 | 450 | } |
fujie@8001 | 451 | } |
fujie@8001 | 452 | } |
aoqi@1 | 453 | } |
aoqi@1 | 454 | |
aoqi@1 | 455 | void Assembler::sdl(Register rt, Address dst) { |
aoqi@6880 | 456 | sdl(rt, dst.base(), dst.disp()); |
aoqi@1 | 457 | } |
aoqi@1 | 458 | |
aoqi@1 | 459 | void Assembler::sdr(Register rt, Address dst) { |
aoqi@6880 | 460 | sdr(rt, dst.base(), dst.disp()); |
aoqi@1 | 461 | } |
aoqi@1 | 462 | |
aoqi@1 | 463 | void Assembler::sh(Register rt, Address dst) { |
aoqi@6880 | 464 | sh(rt, dst.base(), dst.disp()); |
aoqi@1 | 465 | } |
aoqi@1 | 466 | |
aoqi@1 | 467 | void Assembler::sw(Register rt, Address dst) { |
fujie@8001 | 468 | Register src = rt; |
fujie@8001 | 469 | Register base = dst.base(); |
fujie@8001 | 470 | Register index = dst.index(); |
fujie@8001 | 471 | |
fujie@8001 | 472 | int scale = dst.scale(); |
fujie@8001 | 473 | int disp = dst.disp(); |
fujie@8001 | 474 | |
fujie@8001 | 475 | if(index != noreg) { |
fujie@8001 | 476 | if( Assembler::is_simm16(disp) ) { |
fujie@8001 | 477 | if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) { |
fujie@8001 | 478 | if (scale == 0) { |
fujie@8001 | 479 | gsswx(src, base, index, disp); |
fujie@8001 | 480 | } else { |
fujie@8001 | 481 | dsll(AT, index, scale); |
fujie@8001 | 482 | gsswx(src, base, AT, disp); |
fujie@8001 | 483 | } |
fujie@8001 | 484 | } else { |
fujie@8001 | 485 | if (scale == 0) { |
fujie@8001 | 486 | daddu(AT, base, index); |
fujie@8001 | 487 | } else { |
fujie@8001 | 488 | dsll(AT, index, scale); |
fujie@8001 | 489 | daddu(AT, base, AT); |
fujie@8001 | 490 | } |
fujie@8001 | 491 | sw(src, AT, disp); |
fujie@8001 | 492 | } |
fujie@8001 | 493 | } else { |
fujie@8001 | 494 | if (scale == 0) { |
fujie@8001 | 495 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 496 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 497 | daddu(AT, AT, base); |
fujie@8001 | 498 | if( UseLoongsonISA ) { |
fujie@8001 | 499 | gsswx(src, AT, index, 0); |
fujie@8001 | 500 | } else { |
fujie@8001 | 501 | daddu(AT, AT, index); |
fujie@8001 | 502 | sw(src, AT, 0); |
fujie@8001 | 503 | } |
fujie@8001 | 504 | } else { |
fujie@8001 | 505 | dsll(AT, index, scale); |
fujie@8001 | 506 | daddu(AT, base, AT); |
fujie@8001 | 507 | lui(T9, split_low(disp >> 16)); |
fujie@8001 | 508 | if (split_low(disp)) ori(T9, T9, split_low(disp)); |
fujie@8001 | 509 | if( UseLoongsonISA ) { |
fujie@8001 | 510 | gsswx(src, AT, T9, 0); |
fujie@8001 | 511 | } else { |
fujie@8001 | 512 | daddu(AT, AT, T9); |
fujie@8001 | 513 | sw(src, AT, 0); |
fujie@8001 | 514 | } |
fujie@8001 | 515 | } |
fujie@8001 | 516 | } |
fujie@8001 | 517 | } else { |
fujie@8001 | 518 | if( Assembler::is_simm16(disp) ) { |
fujie@8001 | 519 | sw(src, base, disp); |
fujie@8001 | 520 | } else { |
fujie@8001 | 521 | lui(AT, split_low(disp >> 16)); |
fujie@8001 | 522 | if (split_low(disp)) ori(AT, AT, split_low(disp)); |
fujie@8001 | 523 | |
fujie@8001 | 524 | if( UseLoongsonISA ) { |
fujie@8001 | 525 | gsswx(src, base, AT, 0); |
fujie@8001 | 526 | } else { |
fujie@8001 | 527 | daddu(AT, base, AT); |
fujie@8001 | 528 | sw(src, AT, 0); |
fujie@8001 | 529 | } |
fujie@8001 | 530 | } |
fujie@8001 | 531 | } |
aoqi@1 | 532 | } |
aoqi@1 | 533 | |
aoqi@1 | 534 | void Assembler::swl(Register rt, Address dst) { |
aoqi@6880 | 535 | swl(rt, dst.base(), dst.disp()); |
aoqi@1 | 536 | } |
aoqi@1 | 537 | |
aoqi@1 | 538 | void Assembler::swr(Register rt, Address dst) { |
aoqi@6880 | 539 | swr(rt, dst.base(), dst.disp()); |
aoqi@1 | 540 | } |
aoqi@1 | 541 | |
aoqi@1 | 542 | void Assembler::lwc1(FloatRegister rt, Address src) { |
aoqi@6880 | 543 | lwc1(rt, src.base(), src.disp()); |
aoqi@1 | 544 | } |
aoqi@1 | 545 | |
aoqi@1 | 546 | void Assembler::ldc1(FloatRegister rt, Address src) { |
aoqi@6880 | 547 | ldc1(rt, src.base(), src.disp()); |
aoqi@1 | 548 | } |
aoqi@1 | 549 | |
aoqi@1 | 550 | void Assembler::swc1(FloatRegister rt, Address dst) { |
aoqi@6880 | 551 | swc1(rt, dst.base(), dst.disp()); |
aoqi@1 | 552 | } |
aoqi@1 | 553 | |
aoqi@1 | 554 | void Assembler::sdc1(FloatRegister rt, Address dst) { |
aoqi@6880 | 555 | sdc1(rt, dst.base(), dst.disp()); |
aoqi@1 | 556 | } |
aoqi@1 | 557 | |
aoqi@1 | 558 | void Assembler::j(address entry) { |
fujie@378 | 559 | #ifdef MIPS64 |
aoqi@6880 | 560 | int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xfffffffff0000000))>>2; |
fujie@378 | 561 | #else |
aoqi@6880 | 562 | int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xf0000000))>>2; |
fujie@378 | 563 | #endif |
aoqi@6880 | 564 | emit_long((j_op<<26) | dest); |
aoqi@6880 | 565 | has_delay_slot(); |
aoqi@1 | 566 | } |
aoqi@1 | 567 | |
aoqi@1 | 568 | void Assembler::jal(address entry) { |
fujie@378 | 569 | #ifdef MIPS64 |
aoqi@6880 | 570 | int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xfffffffff0000000))>>2; |
fujie@378 | 571 | #else |
aoqi@6880 | 572 | int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xf0000000))>>2; |
fujie@378 | 573 | #endif |
aoqi@6880 | 574 | emit_long((jal_op<<26) | dest); |
aoqi@6880 | 575 | has_delay_slot(); |
aoqi@1 | 576 | } |
aoqi@1 | 577 | |
aoqi@30 | 578 | |
aoqi@1 | 579 | class ControlWord { |
aoqi@6880 | 580 | public: |
aoqi@6880 | 581 | int32_t _value; |
aoqi@1 | 582 | |
aoqi@1 | 583 | int rounding_control() const { return (_value >> 10) & 3 ; } |
aoqi@1 | 584 | int precision_control() const { return (_value >> 8) & 3 ; } |
aoqi@1 | 585 | bool precision() const { return ((_value >> 5) & 1) != 0; } |
aoqi@1 | 586 | bool underflow() const { return ((_value >> 4) & 1) != 0; } |
aoqi@1 | 587 | bool overflow() const { return ((_value >> 3) & 1) != 0; } |
aoqi@1 | 588 | bool zero_divide() const { return ((_value >> 2) & 1) != 0; } |
aoqi@1 | 589 | bool denormalized() const { return ((_value >> 1) & 1) != 0; } |
aoqi@1 | 590 | bool invalid() const { return ((_value >> 0) & 1) != 0; } |
aoqi@1 | 591 | |
aoqi@1 | 592 | void print() const { |
aoqi@1 | 593 | // rounding control |
aoqi@1 | 594 | const char* rc; |
aoqi@1 | 595 | switch (rounding_control()) { |
aoqi@1 | 596 | case 0: rc = "round near"; break; |
aoqi@1 | 597 | case 1: rc = "round down"; break; |
aoqi@1 | 598 | case 2: rc = "round up "; break; |
aoqi@1 | 599 | case 3: rc = "chop "; break; |
aoqi@1 | 600 | }; |
aoqi@1 | 601 | // precision control |
aoqi@1 | 602 | const char* pc; |
aoqi@1 | 603 | switch (precision_control()) { |
aoqi@1 | 604 | case 0: pc = "24 bits "; break; |
aoqi@1 | 605 | case 1: pc = "reserved"; break; |
aoqi@1 | 606 | case 2: pc = "53 bits "; break; |
aoqi@1 | 607 | case 3: pc = "64 bits "; break; |
aoqi@1 | 608 | }; |
aoqi@1 | 609 | // flags |
aoqi@1 | 610 | char f[9]; |
aoqi@1 | 611 | f[0] = ' '; |
aoqi@1 | 612 | f[1] = ' '; |
aoqi@1 | 613 | f[2] = (precision ()) ? 'P' : 'p'; |
aoqi@1 | 614 | f[3] = (underflow ()) ? 'U' : 'u'; |
aoqi@1 | 615 | f[4] = (overflow ()) ? 'O' : 'o'; |
aoqi@1 | 616 | f[5] = (zero_divide ()) ? 'Z' : 'z'; |
aoqi@1 | 617 | f[6] = (denormalized()) ? 'D' : 'd'; |
aoqi@1 | 618 | f[7] = (invalid ()) ? 'I' : 'i'; |
aoqi@1 | 619 | f[8] = '\x0'; |
aoqi@1 | 620 | // output |
aoqi@1 | 621 | printf("%04x masks = %s, %s, %s", _value & 0xFFFF, f, rc, pc); |
aoqi@1 | 622 | } |
aoqi@1 | 623 | |
aoqi@1 | 624 | }; |
aoqi@1 | 625 | |
aoqi@1 | 626 | class StatusWord { |
aoqi@1 | 627 | public: |
aoqi@1 | 628 | int32_t _value; |
aoqi@1 | 629 | |
aoqi@1 | 630 | bool busy() const { return ((_value >> 15) & 1) != 0; } |
aoqi@1 | 631 | bool C3() const { return ((_value >> 14) & 1) != 0; } |
aoqi@1 | 632 | bool C2() const { return ((_value >> 10) & 1) != 0; } |
aoqi@1 | 633 | bool C1() const { return ((_value >> 9) & 1) != 0; } |
aoqi@1 | 634 | bool C0() const { return ((_value >> 8) & 1) != 0; } |
aoqi@1 | 635 | int top() const { return (_value >> 11) & 7 ; } |
aoqi@1 | 636 | bool error_status() const { return ((_value >> 7) & 1) != 0; } |
aoqi@1 | 637 | bool stack_fault() const { return ((_value >> 6) & 1) != 0; } |
aoqi@1 | 638 | bool precision() const { return ((_value >> 5) & 1) != 0; } |
aoqi@1 | 639 | bool underflow() const { return ((_value >> 4) & 1) != 0; } |
aoqi@1 | 640 | bool overflow() const { return ((_value >> 3) & 1) != 0; } |
aoqi@1 | 641 | bool zero_divide() const { return ((_value >> 2) & 1) != 0; } |
aoqi@1 | 642 | bool denormalized() const { return ((_value >> 1) & 1) != 0; } |
aoqi@1 | 643 | bool invalid() const { return ((_value >> 0) & 1) != 0; } |
aoqi@1 | 644 | |
aoqi@1 | 645 | void print() const { |
aoqi@1 | 646 | // condition codes |
aoqi@1 | 647 | char c[5]; |
aoqi@1 | 648 | c[0] = (C3()) ? '3' : '-'; |
aoqi@1 | 649 | c[1] = (C2()) ? '2' : '-'; |
aoqi@1 | 650 | c[2] = (C1()) ? '1' : '-'; |
aoqi@1 | 651 | c[3] = (C0()) ? '0' : '-'; |
aoqi@1 | 652 | c[4] = '\x0'; |
aoqi@1 | 653 | // flags |
aoqi@1 | 654 | char f[9]; |
aoqi@1 | 655 | f[0] = (error_status()) ? 'E' : '-'; |
aoqi@1 | 656 | f[1] = (stack_fault ()) ? 'S' : '-'; |
aoqi@1 | 657 | f[2] = (precision ()) ? 'P' : '-'; |
aoqi@1 | 658 | f[3] = (underflow ()) ? 'U' : '-'; |
aoqi@1 | 659 | f[4] = (overflow ()) ? 'O' : '-'; |
aoqi@1 | 660 | f[5] = (zero_divide ()) ? 'Z' : '-'; |
aoqi@1 | 661 | f[6] = (denormalized()) ? 'D' : '-'; |
aoqi@1 | 662 | f[7] = (invalid ()) ? 'I' : '-'; |
aoqi@1 | 663 | f[8] = '\x0'; |
aoqi@1 | 664 | // output |
aoqi@1 | 665 | printf("%04x flags = %s, cc = %s, top = %d", _value & 0xFFFF, f, c, top()); |
aoqi@1 | 666 | } |
aoqi@1 | 667 | |
aoqi@1 | 668 | }; |
aoqi@1 | 669 | |
aoqi@1 | 670 | class TagWord { |
aoqi@1 | 671 | public: |
aoqi@1 | 672 | int32_t _value; |
aoqi@1 | 673 | |
aoqi@1 | 674 | int tag_at(int i) const { return (_value >> (i*2)) & 3; } |
aoqi@1 | 675 | |
aoqi@1 | 676 | void print() const { |
aoqi@1 | 677 | printf("%04x", _value & 0xFFFF); |
aoqi@1 | 678 | } |
aoqi@1 | 679 | |
aoqi@1 | 680 | }; |
aoqi@1 | 681 | |
aoqi@1 | 682 | class FPU_Register { |
aoqi@1 | 683 | public: |
aoqi@1 | 684 | int32_t _m0; |
aoqi@1 | 685 | int32_t _m1; |
aoqi@1 | 686 | int16_t _ex; |
aoqi@1 | 687 | |
aoqi@1 | 688 | bool is_indefinite() const { |
aoqi@1 | 689 | return _ex == -1 && _m1 == (int32_t)0xC0000000 && _m0 == 0; |
aoqi@1 | 690 | } |
aoqi@1 | 691 | |
aoqi@1 | 692 | void print() const { |
aoqi@1 | 693 | char sign = (_ex < 0) ? '-' : '+'; |
aoqi@1 | 694 | const char* kind = (_ex == 0x7FFF || _ex == (int16_t)-1) ? "NaN" : " "; |
aoqi@1 | 695 | printf("%c%04hx.%08x%08x %s", sign, _ex, _m1, _m0, kind); |
aoqi@1 | 696 | }; |
aoqi@1 | 697 | |
aoqi@1 | 698 | }; |
aoqi@1 | 699 | |
aoqi@1 | 700 | class FPU_State { |
aoqi@1 | 701 | public: |
aoqi@1 | 702 | enum { |
aoqi@1 | 703 | register_size = 10, |
aoqi@1 | 704 | number_of_registers = 8, |
aoqi@1 | 705 | register_mask = 7 |
aoqi@1 | 706 | }; |
aoqi@1 | 707 | |
aoqi@1 | 708 | ControlWord _control_word; |
aoqi@1 | 709 | StatusWord _status_word; |
aoqi@1 | 710 | TagWord _tag_word; |
aoqi@1 | 711 | int32_t _error_offset; |
aoqi@1 | 712 | int32_t _error_selector; |
aoqi@1 | 713 | int32_t _data_offset; |
aoqi@1 | 714 | int32_t _data_selector; |
aoqi@1 | 715 | int8_t _register[register_size * number_of_registers]; |
aoqi@1 | 716 | |
aoqi@1 | 717 | int tag_for_st(int i) const { return _tag_word.tag_at((_status_word.top() + i) & register_mask); } |
aoqi@1 | 718 | FPU_Register* st(int i) const { return (FPU_Register*)&_register[register_size * i]; } |
aoqi@1 | 719 | |
aoqi@1 | 720 | const char* tag_as_string(int tag) const { |
aoqi@1 | 721 | switch (tag) { |
aoqi@1 | 722 | case 0: return "valid"; |
aoqi@1 | 723 | case 1: return "zero"; |
aoqi@1 | 724 | case 2: return "special"; |
aoqi@1 | 725 | case 3: return "empty"; |
aoqi@1 | 726 | } |
aoqi@1 | 727 | ShouldNotReachHere(); |
aoqi@1 | 728 | return NULL; |
aoqi@1 | 729 | } |
aoqi@1 | 730 | |
aoqi@1 | 731 | void print() const { |
aoqi@1 | 732 | // print computation registers |
aoqi@1 | 733 | { int t = _status_word.top(); |
aoqi@1 | 734 | for (int i = 0; i < number_of_registers; i++) { |
aoqi@1 | 735 | int j = (i - t) & register_mask; |
aoqi@1 | 736 | printf("%c r%d = ST%d = ", (j == 0 ? '*' : ' '), i, j); |
aoqi@1 | 737 | st(j)->print(); |
aoqi@1 | 738 | printf(" %s\n", tag_as_string(_tag_word.tag_at(i))); |
aoqi@1 | 739 | } |
aoqi@1 | 740 | } |
aoqi@1 | 741 | printf("\n"); |
aoqi@1 | 742 | // print control registers |
aoqi@1 | 743 | printf("ctrl = "); _control_word.print(); printf("\n"); |
aoqi@1 | 744 | printf("stat = "); _status_word .print(); printf("\n"); |
aoqi@1 | 745 | printf("tags = "); _tag_word .print(); printf("\n"); |
aoqi@1 | 746 | } |
aoqi@1 | 747 | |
aoqi@1 | 748 | }; |
aoqi@1 | 749 | |
aoqi@1 | 750 | class Flag_Register { |
aoqi@1 | 751 | public: |
aoqi@1 | 752 | int32_t _value; |
aoqi@1 | 753 | |
aoqi@1 | 754 | bool overflow() const { return ((_value >> 11) & 1) != 0; } |
aoqi@1 | 755 | bool direction() const { return ((_value >> 10) & 1) != 0; } |
aoqi@1 | 756 | bool sign() const { return ((_value >> 7) & 1) != 0; } |
aoqi@1 | 757 | bool zero() const { return ((_value >> 6) & 1) != 0; } |
aoqi@1 | 758 | bool auxiliary_carry() const { return ((_value >> 4) & 1) != 0; } |
aoqi@1 | 759 | bool parity() const { return ((_value >> 2) & 1) != 0; } |
aoqi@1 | 760 | bool carry() const { return ((_value >> 0) & 1) != 0; } |
aoqi@1 | 761 | |
aoqi@1 | 762 | void print() const { |
aoqi@1 | 763 | // flags |
aoqi@1 | 764 | char f[8]; |
aoqi@1 | 765 | f[0] = (overflow ()) ? 'O' : '-'; |
aoqi@1 | 766 | f[1] = (direction ()) ? 'D' : '-'; |
aoqi@1 | 767 | f[2] = (sign ()) ? 'S' : '-'; |
aoqi@1 | 768 | f[3] = (zero ()) ? 'Z' : '-'; |
aoqi@1 | 769 | f[4] = (auxiliary_carry()) ? 'A' : '-'; |
aoqi@1 | 770 | f[5] = (parity ()) ? 'P' : '-'; |
aoqi@1 | 771 | f[6] = (carry ()) ? 'C' : '-'; |
aoqi@1 | 772 | f[7] = '\x0'; |
aoqi@1 | 773 | // output |
aoqi@1 | 774 | printf("%08x flags = %s", _value, f); |
aoqi@1 | 775 | } |
aoqi@1 | 776 | |
aoqi@1 | 777 | }; |
aoqi@1 | 778 | |
aoqi@1 | 779 | class IU_Register { |
aoqi@1 | 780 | public: |
aoqi@1 | 781 | int32_t _value; |
aoqi@1 | 782 | |
aoqi@1 | 783 | void print() const { |
aoqi@1 | 784 | printf("%08x %11d", _value, _value); |
aoqi@1 | 785 | } |
aoqi@1 | 786 | |
aoqi@1 | 787 | }; |
aoqi@1 | 788 | |
aoqi@1 | 789 | class IU_State { |
aoqi@1 | 790 | public: |
aoqi@1 | 791 | Flag_Register _eflags; |
aoqi@1 | 792 | IU_Register _rdi; |
aoqi@1 | 793 | IU_Register _rsi; |
aoqi@1 | 794 | IU_Register _rbp; |
aoqi@1 | 795 | IU_Register _rsp; |
aoqi@1 | 796 | IU_Register _rbx; |
aoqi@1 | 797 | IU_Register _rdx; |
aoqi@1 | 798 | IU_Register _rcx; |
aoqi@1 | 799 | IU_Register _rax; |
aoqi@1 | 800 | |
aoqi@1 | 801 | void print() const { |
aoqi@1 | 802 | // computation registers |
aoqi@1 | 803 | printf("rax, = "); _rax.print(); printf("\n"); |
aoqi@1 | 804 | printf("rbx, = "); _rbx.print(); printf("\n"); |
aoqi@1 | 805 | printf("rcx = "); _rcx.print(); printf("\n"); |
aoqi@1 | 806 | printf("rdx = "); _rdx.print(); printf("\n"); |
aoqi@1 | 807 | printf("rdi = "); _rdi.print(); printf("\n"); |
aoqi@1 | 808 | printf("rsi = "); _rsi.print(); printf("\n"); |
aoqi@1 | 809 | printf("rbp, = "); _rbp.print(); printf("\n"); |
aoqi@1 | 810 | printf("rsp = "); _rsp.print(); printf("\n"); |
aoqi@1 | 811 | printf("\n"); |
aoqi@1 | 812 | // control registers |
aoqi@1 | 813 | printf("flgs = "); _eflags.print(); printf("\n"); |
aoqi@1 | 814 | } |
aoqi@1 | 815 | }; |
aoqi@1 | 816 | |
aoqi@1 | 817 | |
aoqi@1 | 818 | class CPU_State { |
aoqi@1 | 819 | public: |
aoqi@1 | 820 | FPU_State _fpu_state; |
aoqi@1 | 821 | IU_State _iu_state; |
aoqi@1 | 822 | |
aoqi@1 | 823 | void print() const { |
aoqi@1 | 824 | printf("--------------------------------------------------\n"); |
aoqi@1 | 825 | _iu_state .print(); |
aoqi@1 | 826 | printf("\n"); |
aoqi@1 | 827 | _fpu_state.print(); |
aoqi@1 | 828 | printf("--------------------------------------------------\n"); |
aoqi@1 | 829 | } |
aoqi@1 | 830 | |
aoqi@1 | 831 | }; |
aoqi@1 | 832 | |
aoqi@1 | 833 | |
aoqi@1 | 834 | |
aoqi@1 | 835 |