* Get a suitable scratch register. */
| 217 | * Get a suitable scratch register. |
| 218 | */ |
| 219 | Register getScratch(const Register *exclude = nullptr) |
| 220 | { |
| 221 | Register reg = REGISTER_INVALID; |
| 222 | for (const auto &entry: info) |
| 223 | { |
| 224 | int regno = getRegIdx(entry.first); |
| 225 | if (regno < 0 || regno == FLAGS_IDX || regno == RSP_IDX || |
| 226 | regno == RIP_IDX) |
| 227 | continue; |
| 228 | bool found = false; |
| 229 | for (unsigned i = 0; !found && exclude != nullptr && |
| 230 | exclude[i] != REGISTER_INVALID; i++) |
| 231 | found = (entry.first == exclude[i]); |
| 232 | if (found) |
| 233 | continue; |
| 234 | const RegInfo &rinfo = entry.second; |
| 235 | if (rinfo.used) |
| 236 | continue; |
| 237 | if (rinfo.clobbered) |
| 238 | return entry.first; |
| 239 | if (rinfo.saved) |
| 240 | reg = entry.first; |
| 241 | } |
| 242 | return reg; |
| 243 | } |
| 244 | |
| 245 | /* |
| 246 | * Emulate a register push. |
no test coverage detected