OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 private: | 65 private: |
66 static const instr_t kBreakpointInstr = | 66 static const instr_t kBreakpointInstr = |
67 ((AL << 28) | (7 << 25) | (1 << 24) | break_point); | 67 ((AL << 28) | (7 << 25) | (1 << 24) | break_point); |
68 static const instr_t kNopInstr = | 68 static const instr_t kNopInstr = |
69 ((AL << 28) | (13 << 21)); | 69 ((AL << 28) | (13 << 21)); |
70 | 70 |
71 Simulator* sim_; | 71 Simulator* sim_; |
72 | 72 |
73 int32_t GetRegisterValue(int regnum); | 73 int32_t GetRegisterValue(int regnum); |
74 bool GetValue(const char* desc, int32_t* value); | 74 bool GetValue(const char* desc, int32_t* value); |
| 75 bool GetVFPSingleValue(const char* desc, float* value); |
| 76 bool GetVFPDoubleValue(const char* desc, double* value); |
75 | 77 |
76 // Set or delete a breakpoint. Returns true if successful. | 78 // Set or delete a breakpoint. Returns true if successful. |
77 bool SetBreakpoint(Instr* breakpc); | 79 bool SetBreakpoint(Instr* breakpc); |
78 bool DeleteBreakpoint(Instr* breakpc); | 80 bool DeleteBreakpoint(Instr* breakpc); |
79 | 81 |
80 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 82 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
81 // execution to skip past breakpoints when run from the debugger. | 83 // execution to skip past breakpoints when run from the debugger. |
82 void UndoBreakpoints(); | 84 void UndoBreakpoints(); |
83 void RedoBreakpoints(); | 85 void RedoBreakpoints(); |
84 }; | 86 }; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 if (regnum != kNoRegister) { | 149 if (regnum != kNoRegister) { |
148 *value = GetRegisterValue(regnum); | 150 *value = GetRegisterValue(regnum); |
149 return true; | 151 return true; |
150 } else { | 152 } else { |
151 return SScanF(desc, "%i", value) == 1; | 153 return SScanF(desc, "%i", value) == 1; |
152 } | 154 } |
153 return false; | 155 return false; |
154 } | 156 } |
155 | 157 |
156 | 158 |
| 159 bool Debugger::GetVFPSingleValue(const char* desc, float* value) { |
| 160 bool is_double; |
| 161 int regnum = VFPRegisters::Number(desc, &is_double); |
| 162 if (regnum != kNoRegister && !is_double) { |
| 163 *value = sim_->get_float_from_s_register(regnum); |
| 164 return true; |
| 165 } |
| 166 return false; |
| 167 } |
| 168 |
| 169 |
| 170 bool Debugger::GetVFPDoubleValue(const char* desc, double* value) { |
| 171 bool is_double; |
| 172 int regnum = VFPRegisters::Number(desc, &is_double); |
| 173 if (regnum != kNoRegister && is_double) { |
| 174 *value = sim_->get_double_from_d_register(regnum); |
| 175 return true; |
| 176 } |
| 177 return false; |
| 178 } |
| 179 |
| 180 |
157 bool Debugger::SetBreakpoint(Instr* breakpc) { | 181 bool Debugger::SetBreakpoint(Instr* breakpc) { |
158 // Check if a breakpoint can be set. If not return without any side-effects. | 182 // Check if a breakpoint can be set. If not return without any side-effects. |
159 if (sim_->break_pc_ != NULL) { | 183 if (sim_->break_pc_ != NULL) { |
160 return false; | 184 return false; |
161 } | 185 } |
162 | 186 |
163 // Set the breakpoint. | 187 // Set the breakpoint. |
164 sim_->break_pc_ = breakpc; | 188 sim_->break_pc_ = breakpc; |
165 sim_->break_instr_ = breakpc->InstructionBits(); | 189 sim_->break_instr_ = breakpc->InstructionBits(); |
166 // Not setting the breakpoint instruction in the code itself. It will be set | 190 // Not setting the breakpoint instruction in the code itself. It will be set |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { | 266 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { |
243 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 267 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); |
244 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { | 268 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { |
245 // Execute the one instruction we broke at with breakpoints disabled. | 269 // Execute the one instruction we broke at with breakpoints disabled. |
246 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 270 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); |
247 // Leave the debugger shell. | 271 // Leave the debugger shell. |
248 done = true; | 272 done = true; |
249 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { | 273 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { |
250 if (args == 2) { | 274 if (args == 2) { |
251 int32_t value; | 275 int32_t value; |
| 276 float svalue; |
| 277 double dvalue; |
252 if (strcmp(arg1, "all") == 0) { | 278 if (strcmp(arg1, "all") == 0) { |
253 for (int i = 0; i < kNumRegisters; i++) { | 279 for (int i = 0; i < kNumRegisters; i++) { |
254 value = GetRegisterValue(i); | 280 value = GetRegisterValue(i); |
255 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); | 281 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); |
256 } | 282 } |
257 } else { | 283 } else { |
258 if (GetValue(arg1, &value)) { | 284 if (GetValue(arg1, &value)) { |
259 PrintF("%s: 0x%08x %d \n", arg1, value, value); | 285 PrintF("%s: 0x%08x %d \n", arg1, value, value); |
| 286 } else if (GetVFPSingleValue(arg1, &svalue)) { |
| 287 PrintF("%s: %f \n", arg1, svalue); |
| 288 } else if (GetVFPDoubleValue(arg1, &dvalue)) { |
| 289 PrintF("%s: %lf \n", arg1, dvalue); |
260 } else { | 290 } else { |
261 PrintF("%s unrecognized\n", arg1); | 291 PrintF("%s unrecognized\n", arg1); |
262 } | 292 } |
263 } | 293 } |
264 } else { | 294 } else { |
265 PrintF("print <register>\n"); | 295 PrintF("print <register>\n"); |
266 } | 296 } |
267 } else if ((strcmp(cmd, "po") == 0) | 297 } else if ((strcmp(cmd, "po") == 0) |
268 || (strcmp(cmd, "printobject") == 0)) { | 298 || (strcmp(cmd, "printobject") == 0)) { |
269 if (args == 2) { | 299 if (args == 2) { |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1912 // Not sign extending, so load as unsigned. | 1942 // Not sign extending, so load as unsigned. |
1913 uint16_t halfword = ReadH(addr, instr); | 1943 uint16_t halfword = ReadH(addr, instr); |
1914 set_register(rd, halfword); | 1944 set_register(rd, halfword); |
1915 } else { | 1945 } else { |
1916 Debugger dbg(this); | 1946 Debugger dbg(this); |
1917 dbg.Stop(instr); | 1947 dbg.Stop(instr); |
1918 } | 1948 } |
1919 } | 1949 } |
1920 | 1950 |
1921 | 1951 |
| 1952 // Depending on value of last_bit flag glue register code from vm and m values |
| 1953 // (where m is expected to be a single bit). |
| 1954 static int GlueRegCode(bool last_bit, int vm, int m) { |
| 1955 return last_bit ? ((vm << 1) | m) : ((m << 4) | vm); |
| 1956 } |
| 1957 |
| 1958 |
1922 // void Simulator::DecodeTypeVFP(Instr* instr) | 1959 // void Simulator::DecodeTypeVFP(Instr* instr) |
1923 // The Following ARMv7 VFPv instructions are currently supported. | 1960 // The Following ARMv7 VFPv instructions are currently supported. |
1924 // vmov :Sn = Rt | 1961 // vmov :Sn = Rt |
1925 // vmov :Rt = Sn | 1962 // vmov :Rt = Sn |
1926 // vcvt: Dd = Sm | 1963 // vcvt: Dd = Sm |
1927 // vcvt: Sd = Dm | 1964 // vcvt: Sd = Dm |
1928 // Dd = vadd(Dn, Dm) | 1965 // Dd = vadd(Dn, Dm) |
1929 // Dd = vsub(Dn, Dm) | 1966 // Dd = vsub(Dn, Dm) |
1930 // Dd = vmul(Dn, Dm) | 1967 // Dd = vmul(Dn, Dm) |
1931 // Dd = vdiv(Dn, Dm) | 1968 // Dd = vdiv(Dn, Dm) |
1932 // vcmp(Dd, Dm) | 1969 // vcmp(Dd, Dm) |
1933 // VMRS | 1970 // VMRS |
1934 void Simulator::DecodeTypeVFP(Instr* instr) { | 1971 void Simulator::DecodeTypeVFP(Instr* instr) { |
1935 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); | 1972 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); |
1936 | 1973 ASSERT(instr->Bits(11, 9) == 0x5); |
1937 int rt = instr->RtField(); | 1974 |
1938 int vm = instr->VmField(); | 1975 int vm = instr->VmField(); |
| 1976 int vd = instr->VdField(); |
1939 int vn = instr->VnField(); | 1977 int vn = instr->VnField(); |
1940 int vd = instr->VdField(); | 1978 |
1941 | 1979 if (instr->Bit(4) == 0) { |
1942 if (instr->Bit(23) == 1) { | 1980 if (instr->Opc1Field() == 0x7) { |
1943 if ((instr->Bits(21, 19) == 0x7) && | 1981 // Other data processing instructions |
1944 (instr->Bits(18, 16) == 0x5) && | 1982 if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) { |
1945 (instr->Bits(11, 9) == 0x5) && | 1983 DecodeVCVTBetweenDoubleAndSingle(instr); |
1946 (instr->Bit(8) == 1) && | 1984 } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) { |
1947 (instr->Bit(6) == 1) && | 1985 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
1948 (instr->Bit(4) == 0)) { | 1986 } else if (((instr->Opc2Field() >> 1) == 0x6) && |
1949 double dm_val = get_double_from_d_register(vm); | 1987 (instr->Opc3Field() & 0x1)) { |
1950 int32_t int_value = static_cast<int32_t>(dm_val); | 1988 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
1951 set_s_register_from_sinteger(((vd<<1) | instr->DField()), int_value); | 1989 } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && |
1952 } else if ((instr->Bits(21, 19) == 0x7) && | 1990 (instr->Opc3Field() & 0x1)) { |
1953 (instr->Bits(18, 16) == 0x0) && | 1991 DecodeVCMP(instr); |
1954 (instr->Bits(11, 9) == 0x5) && | 1992 } else { |
1955 (instr->Bit(8) == 1) && | 1993 UNREACHABLE(); // Not used by V8. |
1956 (instr->Bit(7) == 1) && | 1994 } |
1957 (instr->Bit(6) == 1) && | 1995 } else if (instr->Opc1Field() == 0x3) { |
1958 (instr->Bit(4) == 0)) { | 1996 if (instr->SzField() != 0x1) { |
1959 int32_t int_value = get_sinteger_from_s_register(((vm<<1) | | 1997 UNREACHABLE(); // Not used by V8. |
1960 instr->MField())); | 1998 } |
1961 double dbl_value = static_cast<double>(int_value); | 1999 |
1962 set_d_register_from_double(vd, dbl_value); | 2000 if (instr->Opc3Field() & 0x1) { |
1963 } else if ((instr->Bit(21) == 0x0) && | 2001 // vsub |
1964 (instr->Bit(20) == 0x0) && | 2002 double dn_value = get_double_from_d_register(vn); |
1965 (instr->Bits(11, 9) == 0x5) && | 2003 double dm_value = get_double_from_d_register(vm); |
1966 (instr->Bit(8) == 1) && | 2004 double dd_value = dn_value - dm_value; |
1967 (instr->Bit(6) == 0) && | 2005 set_d_register_from_double(vd, dd_value); |
1968 (instr->Bit(4) == 0)) { | 2006 } else { |
| 2007 // vadd |
| 2008 double dn_value = get_double_from_d_register(vn); |
| 2009 double dm_value = get_double_from_d_register(vm); |
| 2010 double dd_value = dn_value + dm_value; |
| 2011 set_d_register_from_double(vd, dd_value); |
| 2012 } |
| 2013 } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) { |
| 2014 // vmul |
| 2015 if (instr->SzField() != 0x1) { |
| 2016 UNREACHABLE(); // Not used by V8. |
| 2017 } |
| 2018 |
| 2019 double dn_value = get_double_from_d_register(vn); |
| 2020 double dm_value = get_double_from_d_register(vm); |
| 2021 double dd_value = dn_value * dm_value; |
| 2022 set_d_register_from_double(vd, dd_value); |
| 2023 } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) { |
| 2024 // vdiv |
| 2025 if (instr->SzField() != 0x1) { |
| 2026 UNREACHABLE(); // Not used by V8. |
| 2027 } |
| 2028 |
1969 double dn_value = get_double_from_d_register(vn); | 2029 double dn_value = get_double_from_d_register(vn); |
1970 double dm_value = get_double_from_d_register(vm); | 2030 double dm_value = get_double_from_d_register(vm); |
1971 double dd_value = dn_value / dm_value; | 2031 double dd_value = dn_value / dm_value; |
1972 set_d_register_from_double(vd, dd_value); | 2032 set_d_register_from_double(vd, dd_value); |
1973 } else if ((instr->Bits(21, 20) == 0x3) && | 2033 } else { |
1974 (instr->Bits(19, 16) == 0x4) && | 2034 UNIMPLEMENTED(); // Not used by V8. |
1975 (instr->Bits(11, 9) == 0x5) && | 2035 } |
1976 (instr->Bit(8) == 0x1) && | 2036 } else { |
1977 (instr->Bit(6) == 0x1) && | 2037 if ((instr->VCField() == 0x0) && |
1978 (instr->Bit(4) == 0x0)) { | 2038 (instr->VAField() == 0x0)) { |
1979 double dd_value = get_double_from_d_register(vd); | 2039 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
1980 double dm_value = get_double_from_d_register(vm); | 2040 } else if ((instr->VLField() == 0x1) && |
1981 Compute_FPSCR_Flags(dd_value, dm_value); | 2041 (instr->VCField() == 0x0) && |
1982 } else if ((instr->Bits(23, 20) == 0xF) && | 2042 (instr->VAField() == 0x7) && |
1983 (instr->Bits(19, 16) == 0x1) && | 2043 (instr->Bits(19, 16) == 0x1)) { |
1984 (instr->Bits(11, 8) == 0xA) && | 2044 // vmrs |
1985 (instr->Bits(7, 5) == 0x0) && | 2045 if (instr->RtField() == 0xF) |
1986 (instr->Bit(4) == 0x1) && | |
1987 (instr->Bits(3, 0) == 0x0)) { | |
1988 if (instr->Bits(15, 12) == 0xF) | |
1989 Copy_FPSCR_to_APSR(); | 2046 Copy_FPSCR_to_APSR(); |
1990 else | 2047 else |
1991 UNIMPLEMENTED(); // Not used by V8. | 2048 UNIMPLEMENTED(); // Not used by V8. |
1992 } else { | 2049 } else { |
1993 UNIMPLEMENTED(); // Not used by V8. | 2050 UNIMPLEMENTED(); // Not used by V8. |
1994 } | 2051 } |
1995 } else if (instr->Bit(21) == 1) { | 2052 } |
1996 if ((instr->Bit(20) == 0x1) && | 2053 } |
1997 (instr->Bits(11, 9) == 0x5) && | 2054 |
1998 (instr->Bit(8) == 0x1) && | 2055 |
1999 (instr->Bit(6) == 0) && | 2056 void Simulator::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) { |
2000 (instr->Bit(4) == 0)) { | 2057 ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) && |
2001 double dn_value = get_double_from_d_register(vn); | 2058 (instr->VAField() == 0x0)); |
2002 double dm_value = get_double_from_d_register(vm); | 2059 |
2003 double dd_value = dn_value + dm_value; | 2060 int t = instr->RtField(); |
2004 set_d_register_from_double(vd, dd_value); | 2061 int n = GlueRegCode(true, instr->VnField(), instr->NField()); |
2005 } else if ((instr->Bit(20) == 0x1) && | 2062 bool to_arm_register = (instr->VLField() == 0x1); |
2006 (instr->Bits(11, 9) == 0x5) && | 2063 |
2007 (instr->Bit(8) == 0x1) && | 2064 if (to_arm_register) { |
2008 (instr->Bit(6) == 1) && | 2065 int32_t int_value = get_sinteger_from_s_register(n); |
2009 (instr->Bit(4) == 0)) { | 2066 set_register(t, int_value); |
2010 double dn_value = get_double_from_d_register(vn); | 2067 } else { |
2011 double dm_value = get_double_from_d_register(vm); | 2068 int32_t rs_val = get_register(t); |
2012 double dd_value = dn_value - dm_value; | 2069 set_s_register_from_sinteger(n, rs_val); |
2013 set_d_register_from_double(vd, dd_value); | 2070 } |
2014 } else if ((instr->Bit(20) == 0x0) && | 2071 } |
2015 (instr->Bits(11, 9) == 0x5) && | 2072 |
2016 (instr->Bit(8) == 0x1) && | 2073 |
2017 (instr->Bit(6) == 0) && | 2074 void Simulator::DecodeVCMP(Instr* instr) { |
2018 (instr->Bit(4) == 0)) { | 2075 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); |
2019 double dn_value = get_double_from_d_register(vn); | 2076 ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) && |
2020 double dm_value = get_double_from_d_register(vm); | 2077 (instr->Opc3Field() & 0x1)); |
2021 double dd_value = dn_value * dm_value; | 2078 |
2022 set_d_register_from_double(vd, dd_value); | 2079 // Comparison. |
2023 } else { | 2080 bool dp_operation = (instr->SzField() == 1); |
| 2081 |
| 2082 if (instr->Bit(7) != 0) { |
| 2083 // Raising exceptions for quiet NaNs are not supported. |
| 2084 UNIMPLEMENTED(); // Not used by V8. |
| 2085 } |
| 2086 |
| 2087 int d = GlueRegCode(!dp_operation, instr->VdField(), instr->DField()); |
| 2088 int m = GlueRegCode(!dp_operation, instr->VmField(), instr->MField()); |
| 2089 |
| 2090 if (dp_operation) { |
| 2091 double dd_value = get_double_from_d_register(d); |
| 2092 double dm_value = get_double_from_d_register(m); |
| 2093 |
| 2094 Compute_FPSCR_Flags(dd_value, dm_value); |
| 2095 } else { |
| 2096 UNIMPLEMENTED(); // Not used by V8. |
| 2097 } |
| 2098 } |
| 2099 |
| 2100 |
| 2101 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) { |
| 2102 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); |
| 2103 ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)); |
| 2104 |
| 2105 bool double_to_single = (instr->SzField() == 1); |
| 2106 int dst = GlueRegCode(double_to_single, instr->VdField(), instr->DField()); |
| 2107 int src = GlueRegCode(!double_to_single, instr->VmField(), instr->MField()); |
| 2108 |
| 2109 if (double_to_single) { |
| 2110 double val = get_double_from_d_register(src); |
| 2111 set_s_register_from_float(dst, static_cast<float>(val)); |
| 2112 } else { |
| 2113 float val = get_float_from_s_register(src); |
| 2114 set_d_register_from_double(dst, static_cast<double>(val)); |
| 2115 } |
| 2116 } |
| 2117 |
| 2118 |
| 2119 void Simulator::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) { |
| 2120 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7)); |
| 2121 ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) || |
| 2122 (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1))); |
| 2123 |
| 2124 // Conversion between floating-point and integer. |
| 2125 int vd = instr->VdField(); |
| 2126 int d = instr->DField(); |
| 2127 int vm = instr->VmField(); |
| 2128 int m = instr->MField(); |
| 2129 |
| 2130 bool to_integer = (instr->Bit(18) == 1); |
| 2131 bool dp_operation = (instr->SzField() == 1); |
| 2132 if (to_integer) { |
| 2133 bool unsigned_integer = (instr->Bit(16) == 0); |
| 2134 if (instr->Bit(7) != 1) { |
| 2135 // Only rounding towards zero supported. |
2024 UNIMPLEMENTED(); // Not used by V8. | 2136 UNIMPLEMENTED(); // Not used by V8. |
2025 } | 2137 } |
2026 } else { | 2138 |
2027 if ((instr->Bit(20) == 0x0) && | 2139 int dst = GlueRegCode(true, vd, d); |
2028 (instr->Bits(11, 8) == 0xA) && | 2140 int src = GlueRegCode(!dp_operation, vm, m); |
2029 (instr->Bits(6, 5) == 0x0) && | 2141 |
2030 (instr->Bit(4) == 1) && | 2142 if (dp_operation) { |
2031 (instr->Bits(3, 0) == 0x0)) { | 2143 double val = get_double_from_d_register(src); |
2032 int32_t rs_val = get_register(rt); | 2144 |
2033 set_s_register_from_sinteger(((vn<<1) | instr->NField()), rs_val); | 2145 int sint = unsigned_integer ? static_cast<uint32_t>(val) : |
2034 } else if ((instr->Bit(20) == 0x1) && | 2146 static_cast<int32_t>(val); |
2035 (instr->Bits(11, 8) == 0xA) && | 2147 |
2036 (instr->Bits(6, 5) == 0x0) && | 2148 set_s_register_from_sinteger(dst, sint); |
2037 (instr->Bit(4) == 1) && | 2149 } else { |
2038 (instr->Bits(3, 0) == 0x0)) { | 2150 float val = get_float_from_s_register(src); |
2039 int32_t int_value = get_sinteger_from_s_register(((vn<<1) | | 2151 |
2040 instr->NField())); | 2152 int sint = unsigned_integer ? static_cast<uint32_t>(val) : |
2041 set_register(rt, int_value); | 2153 static_cast<int32_t>(val); |
2042 } else { | 2154 |
2043 UNIMPLEMENTED(); // Not used by V8. | 2155 set_s_register_from_sinteger(dst, sint); |
2044 } | 2156 } |
2045 } | 2157 } else { |
2046 } | 2158 bool unsigned_integer = (instr->Bit(7) == 0); |
| 2159 |
| 2160 int dst = GlueRegCode(!dp_operation, vd, d); |
| 2161 int src = GlueRegCode(true, vm, m); |
| 2162 |
| 2163 int val = get_sinteger_from_s_register(src); |
| 2164 |
| 2165 if (dp_operation) { |
| 2166 if (unsigned_integer) { |
| 2167 set_d_register_from_double(dst, |
| 2168 static_cast<double>((uint32_t)val)); |
| 2169 } else { |
| 2170 set_d_register_from_double(dst, static_cast<double>(val)); |
| 2171 } |
| 2172 } else { |
| 2173 if (unsigned_integer) { |
| 2174 set_s_register_from_float(dst, |
| 2175 static_cast<float>((uint32_t)val)); |
| 2176 } else { |
| 2177 set_s_register_from_float(dst, static_cast<float>(val)); |
| 2178 } |
| 2179 } |
| 2180 } |
| 2181 } |
2047 | 2182 |
2048 | 2183 |
2049 // void Simulator::DecodeType6CoprocessorIns(Instr* instr) | 2184 // void Simulator::DecodeType6CoprocessorIns(Instr* instr) |
2050 // Decode Type 6 coprocessor instructions. | 2185 // Decode Type 6 coprocessor instructions. |
2051 // Dm = vmov(Rt, Rt2) | 2186 // Dm = vmov(Rt, Rt2) |
2052 // <Rt, Rt2> = vmov(Dm) | 2187 // <Rt, Rt2> = vmov(Dm) |
2053 // Ddst = MEM(Rbase + 4*offset). | 2188 // Ddst = MEM(Rbase + 4*offset). |
2054 // MEM(Rbase + 4*offset) = Dsrc. | 2189 // MEM(Rbase + 4*offset) = Dsrc. |
2055 void Simulator::DecodeType6CoprocessorIns(Instr* instr) { | 2190 void Simulator::DecodeType6CoprocessorIns(Instr* instr) { |
2056 ASSERT((instr->TypeField() == 6)); | 2191 ASSERT((instr->TypeField() == 6)); |
2057 | 2192 |
2058 if (instr->CoprocessorField() != 0xB) { | 2193 if (instr->CoprocessorField() == 0xA) { |
2059 UNIMPLEMENTED(); // Not used by V8. | 2194 switch (instr->OpcodeField()) { |
2060 } else { | 2195 case 0x8: |
| 2196 case 0xC: { // Load and store float to memory. |
| 2197 int rn = instr->RnField(); |
| 2198 int vd = instr->VdField(); |
| 2199 int offset = instr->Immed8Field(); |
| 2200 if (!instr->HasU()) { |
| 2201 offset = -offset; |
| 2202 } |
| 2203 |
| 2204 int32_t address = get_register(rn) + 4 * offset; |
| 2205 if (instr->HasL()) { |
| 2206 // Load double from memory: vldr. |
| 2207 set_s_register_from_sinteger(vd, ReadW(address, instr)); |
| 2208 } else { |
| 2209 // Store double to memory: vstr. |
| 2210 WriteW(address, get_sinteger_from_s_register(vd), instr); |
| 2211 } |
| 2212 break; |
| 2213 } |
| 2214 default: |
| 2215 UNIMPLEMENTED(); // Not used by V8. |
| 2216 break; |
| 2217 } |
| 2218 } else if (instr->CoprocessorField() == 0xB) { |
2061 switch (instr->OpcodeField()) { | 2219 switch (instr->OpcodeField()) { |
2062 case 0x2: | 2220 case 0x2: |
2063 // Load and store double to two GP registers | 2221 // Load and store double to two GP registers |
2064 if (instr->Bits(7, 4) != 0x1) { | 2222 if (instr->Bits(7, 4) != 0x1) { |
2065 UNIMPLEMENTED(); // Not used by V8. | 2223 UNIMPLEMENTED(); // Not used by V8. |
2066 } else { | 2224 } else { |
2067 int rt = instr->RtField(); | 2225 int rt = instr->RtField(); |
2068 int rn = instr->RnField(); | 2226 int rn = instr->RnField(); |
2069 int vm = instr->VmField(); | 2227 int vm = instr->VmField(); |
2070 if (instr->HasL()) { | 2228 if (instr->HasL()) { |
(...skipping 28 matching lines...) Expand all Loading... |
2099 // Store double to memory: vstr. | 2257 // Store double to memory: vstr. |
2100 WriteW(address, get_sinteger_from_s_register(2*vd), instr); | 2258 WriteW(address, get_sinteger_from_s_register(2*vd), instr); |
2101 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr); | 2259 WriteW(address + 4, get_sinteger_from_s_register(2*vd + 1), instr); |
2102 } | 2260 } |
2103 break; | 2261 break; |
2104 } | 2262 } |
2105 default: | 2263 default: |
2106 UNIMPLEMENTED(); // Not used by V8. | 2264 UNIMPLEMENTED(); // Not used by V8. |
2107 break; | 2265 break; |
2108 } | 2266 } |
| 2267 } else { |
| 2268 UNIMPLEMENTED(); // Not used by V8. |
2109 } | 2269 } |
2110 } | 2270 } |
2111 | 2271 |
2112 | 2272 |
2113 // Executes the current instruction. | 2273 // Executes the current instruction. |
2114 void Simulator::InstructionDecode(Instr* instr) { | 2274 void Simulator::InstructionDecode(Instr* instr) { |
2115 pc_modified_ = false; | 2275 pc_modified_ = false; |
2116 if (::v8::internal::FLAG_trace_sim) { | 2276 if (::v8::internal::FLAG_trace_sim) { |
2117 disasm::NameConverter converter; | 2277 disasm::NameConverter converter; |
2118 disasm::Disassembler dasm(converter); | 2278 disasm::Disassembler dasm(converter); |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 2463 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
2304 uintptr_t address = *stack_slot; | 2464 uintptr_t address = *stack_slot; |
2305 set_register(sp, current_sp + sizeof(uintptr_t)); | 2465 set_register(sp, current_sp + sizeof(uintptr_t)); |
2306 return address; | 2466 return address; |
2307 } | 2467 } |
2308 | 2468 |
2309 | 2469 |
2310 } } // namespace assembler::arm | 2470 } } // namespace assembler::arm |
2311 | 2471 |
2312 #endif // !defined(__arm__) | 2472 #endif // !defined(__arm__) |
OLD | NEW |