Showing preview only (1,529K chars total). Download the full file or copy to clipboard to get everything.
Repository: ozaki-r/arm-js
Branch: master
Commit: 5afce124bfbc
Files: 32
Total size: 1.5 MB
Directory structure:
gitextract_vip1hlxs/
├── .gitmodules
├── Image-3.10.29
├── README.md
├── arm-js.html
├── css/
│ └── jquery-ui-1.8.18.custom.css
├── initramfs.cpio.lzo
├── js/
│ ├── 9p.js
│ ├── JSONlocalStorage.js
│ ├── armv7-cp15.js
│ ├── armv7-cpu.js
│ ├── armv7-mmu.js
│ ├── bitops.js
│ ├── display.js
│ ├── filesystem.js
│ ├── jquery-1.7.2.js
│ ├── logger.js
│ ├── number64.js
│ ├── option.js
│ ├── parameter.js
│ ├── symbols.js
│ ├── tracer.js
│ ├── utils.js
│ ├── vexpress.js
│ └── virtio.js
├── misc/
│ ├── busybox-1.20.2.config
│ ├── jquery-1.7.2-binary.patch
│ ├── linux-3.6.1.config
│ ├── simple-http-server.rb
│ ├── symbols.rb
│ ├── term.js.patch
│ └── vexpress-armjs.dts
└── vexpress-armjs.dtb
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitmodules
================================================
[submodule "js/simpleterm"]
path = js/simpleterm
url = https://github.com/michaelko/simpleterm.git
================================================
FILE: README.md
================================================
Arm-js
======
Arm-js is an ARM emulator written in Javascript. It emulates ARMv7-A
and some peripherals of Versatile Express. It can boot Linux 3.10.29
and run busybox processes.
Emulator Features
---
* Suspend/resume (Chrome only)
* You can restore emulator states at any time
* Persistent storage (Chrome only)
* Guest can access part of browser [filesystem](http://www.w3.org/TR/file-system-api/) via virtio-9p
* Many debugging functions
Tested Browsers
---
* Chrome 33 beta (recommended)
* Firefox 27
Get Started
---
1. Download the source code
1. git clone git://github.com/ozaki-r/arm-js.git
2. cd arm-js/
2. git submodule init
3. git submodule update
2. Execute ruby misc/simple-http-server.rb on terminal
3. Access http://localhost:8080/arm-js.html
4. Push Boot button at the top-left corner to start the emulator
Further Information
---
See the [wiki](https://github.com/ozaki-r/arm-js/wiki).
================================================
FILE: arm-js.html
================================================
<!--
/*!
* Javascript ARMv7 Emulator
*
* Copyright 2012, Ryota Ozaki
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
-->
<html>
<head>
<meta charset="UTF-8">
<script src="js/jquery-1.7.2.js"></script>
<script src="js/jquery-ui-1.8.18.custom.min.js"></script>
<script src="js/symbols.js"></script>
<script src="js/display.js"></script>
<script src="js/logger.js"></script>
<script src="js/tracer.js"></script>
<script src="js/utils.js"></script>
<script src="js/bitops.js"></script>
<script src="js/number64.js"></script>
<script src="js/JSONlocalStorage.js"></script>
<script src="js/option.js"></script>
<script src="js/parameter.js"></script>
<script src="js/simpleterm/term.js"></script>
<script src="js/filesystem.js"></script>
<script src="js/armv7-mmu.js"></script>
<script src="js/armv7-cp15.js"></script>
<script src="js/armv7-cpu.js"></script>
<script src="js/9p.js"></script>
<script src="js/virtio.js"></script>
<script src="js/vexpress.js"></script>
<style>
.term {
font-family: courier,fixed,swiss,monospace,sans-serif;
font-size: 14px;
color: #f0f0f0;
background: #000000;
}
.termReverse {
color: #000000;
background: #00ff00;
}
#note {
font-size: 12px;
}
#copyright {
font-size: 10px;
}
#clipboard {
font-size: 12px;
}
#display {
font-family: courier,fixed,swiss,monospace,sans-serif;
font-size: 12px;
height: 60%;
overflow: scroll;
}
</style>
<link href="css/jquery-ui-1.8.18.custom.css" rel="stylesheet" type="text/css" />
<style>
.ui-widget-content {
font-size: normal;
}
.tab {
font-size: 12px;
}
.ui-widget button, .ui-widget label {
font-size: 12px;
}
</style>
</head>
<body>
<script>
bitops = new BitOps();
options = new Options();
display = new Display("display", options);
logger = new Logger(display, options);
tracer = new Tracer(display, options);
btracer = new BranchTracer(display, options);
$(document).ready(function() {
var parameters = new Parameters();
var configurations = new Configurations();
configurations.read_saved_values(display);
configurations.register_handlers();
var system = new VersatileExpress(configurations, options);
function term_handler(str) {
//system.keyboard.receive_char(str.charCodeAt(0));
system.uart0.input_char(str.charCodeAt(0));
}
var term = new Term(80, 20, term_handler);
system.uart0.write_to_terminal = term.write.bind(term);
var fsAvailable = false;
function system_state_changed_cb() {
if (system.is_booted) {
$("#stack").removeAttr("disabled");
$("#show_page_tables").removeAttr("disabled");
$("#dump_phymem").removeAttr("disabled");
$("#dump_virmem").removeAttr("disabled");
if (system.is_running)
$("#step").attr("disabled", "disabled");
else
$("#step").removeAttr("disabled");
if (fsAvailable && !system.is_running) {
$("#save").removeAttr("disabled");
$("#restore").removeAttr("disabled");
} else {
$("#save").attr("disabled", "disabled");
$("#restore").attr("disabled", "disabled");
}
} else {
if (fsAvailable)
$("#restore").removeAttr("disabled");
$("#save").attr("disabled", "disabled");
$("#step").attr("disabled", "disabled");
$("#stack").attr("disabled", "disabled");
$("#show_page_tables").attr("disabled", "disabled");
$("#dump_phymem").attr("disabled", "disabled");
$("#dump_virmem").attr("disabled", "disabled");
}
if (!system.is_booted)
$("#controller").html("Boot");
else if (!system.is_running)
$("#controller").html("Restart");
else
$("#controller").html("Stop");
}
system.set_state_changed_cb(system_state_changed_cb);
$("#controller").click(function() {
if (!system.is_booted) {
system.boot(parameters);
} else {
if (system.is_running)
system.stop();
else
system.restart();
}
});
$("#step").click(function() {
system.stop_after = 1;
system.restart();
});
$("#save").click(function() {
system.save();
});
$("#restore").click(function() {
system.restore();
logger.reset();
tracer.reset();
btracer.reset();
$("#controller").html("Restart");
});
$("#show_logs").click(function() {
display.wipe();
logger.dump();
});
$("#show_traces").click(function() {
display.wipe();
tracer.dump();
});
$("#show_branch_traces").click(function() {
display.wipe();
btracer.dump();
});
$("#dump").click(function() {
system.dump();
});
$("#stack").click(function() {
system.dump_stack();
});
$("#show_options").click(function() {
display.wipe();
options.dump(display);
});
$("#show_page_tables").click(function() {
system.dump_page_tables();
});
$("#test").click(function() {
bitops.test();
TestNumber64();
});
$("#test_terminal").click(function() {
system.test_terminal();
});
$("#save_options").click(function() {
options.save_to_localStorage();
});
$("#save_parameters").click(function() {
parameters.save_to_localStorage();
configurations.save_to_localStorage();
});
$("#dump_phymem").click(function() {
system.dump_phymem(parseInt($('#phymem_addr').val(), 16));
});
$("#dump_virmem").click(function() {
system.dump_virmem(parseInt($('#virmem_addr').val(), 16));
});
$("#dump_io").click(function() {
system.dump_io();
});
$("#show_counted_instructions").click(function() {
var reversed = new Array();
for (var name in system.inst_counter) {
if (!reversed[system.inst_counter[name]])
reversed[system.inst_counter[name]] = new Array();
reversed[system.inst_counter[name]].push(name);
}
var sorted = new Array(system.inst_counter.length);
for (var name in system.inst_counter) {
sorted.push(system.inst_counter[name]);
}
sorted.sort(function(a, b) { return b - a; });
var output = "";
var done = new Array();
for (var i in sorted) {
if (done[sorted[i]])
continue;
output += sorted[i] + ": " + reversed[sorted[i]].join(", ") + "\n";
done[sorted[i]] = true;
}
display.wipe();
display.log(output);
});
term.open();
options.read_saved_values(display);
options.register_handlers();
parameters.read_saved_values(display);
parameters.register_handlers();
prev = 0.0;
elapsed_time = 0;
function update_instruction_display() {
var display = document.getElementById('inst_counter');
display.innerHTML = system.n_instructions.toString();
if (system.is_running) {
if (prev != 0.0) {
display = document.getElementById('kips');
var kips = (system.n_instructions - prev) / 1000;
display.innerHTML = kips.toFixed(1);
}
prev = system.n_instructions;
display = document.getElementById('elapsed_time');
elapsed_time += 1;
display.innerHTML = elapsed_time.toString();
} else {
display = document.getElementById('kips');
var kips = 0.0;
display.innerHTML = kips.toFixed(1);
prev = system.n_instructions;
}
}
// Test if HTML5 FileSystem is available
fsTestAvailability(50 * 1024 * 1024, function() {
system.enable_virtio_9p();
fsAvailable = true;
system_state_changed_cb();
}, function() {
system_state_changed_cb();
});
setInterval(update_instruction_display, 1000);
});
</script>
<script>
$(function() {
$('#ui-tabs').tabs();
});
</script>
<div id=header>
<button id="controller" type="button">Boot</button>
<button id="step" type="button" disabled>Execute one instruction</button>
/
<button id="save" type="button" disabled>Save system</button>
<button id="restore" type="button" disabled>Restore system</button>
</div>
<div><span id="kips">0.0</span> KIPS / <span id="inst_counter">0</span> instructions executed / <span id="elapsed_time">0</span> sec elapsed</div>
<div id="ui-tabs">
<ul>
<li class="tab"><a href="#tab-1">Emulator Terminal</a></li>
<li class="tab"><a href="#tab-2">Emulator Parameters</a></li>
<li class="tab"><a href="#tab-3">Debug Console</a></li>
<li class="tab"><a href="#tab-4">Debug Options</a></li>
</ul>
<div id="tab-1">
<div id=terminal tabindex=0></div>
</div>
<div id="tab-2">
<fieldset id="configuration">
<legend><label>Machine Configuration</label></legend>
<ul style="list-style-type: none;">
<li><label>Memory Size: <input type=number id=memory_size min=20> MB</label></li>
</ul>
</fieldset>
<fieldset id="boot_parameters">
<legend><label>Boot Parameters</label></legend>
<ul style="list-style-type: none;">
<li><label>Kernel Image: <input type=text id=Image_url size=60></label></li>
<li><label>Kernel cmdline: <input type=text id=cmdline size=60></label></li>
<li><label>Initrd: <input type=text id=initrd_url size=60></label></li>
<li><label>Initrd compressed size: <input type=number id=initrd_size min=0> Byte</label></li>
<li><label>Initrd cpio size: <input type=number id=initrd_decomp_size min=0> Byte</label></li>
<li><label>DTB: <input type=text id=dtb_url size=60></label></li>
</ul>
</fieldset>
<button id="save_parameters" type="button">Save</button>
</div>
<div id="tab-3">
<button id="show_logs" class="button" type="button">Show logs</button>
<button id="show_traces" class="button" type="button">Show traces</button>
<button id="show_branch_traces" class="button" type="button">Show branch traces</button>
<button id="dump" class="button" type="button">Show states</button>
<button id="show_options" class="button" type="button">Show options</button>
<button id="show_counted_instructions" class="button" type="button">Show counted instructions</button>
<button id="test" class="button" type="button">Test</button>
<button id="test_terminal" class="button" type="button">Test terminal</button>
<br />
<button id="stack" class="button" type="button" disabled>Show stack</button>
<button id="show_page_tables" class="button" type="button" disabled>Show page tables</button>
<label>PhyAddr: <input type=text id=phymem_addr placeholder="c0001234" pattern="^(0x)?[0-9a-fA-F]+$"></label>
<button id="dump_phymem" class="button" type="button" disabled>Dump phymem</button>
<label>VirAddr: <input type=text id=virmem_addr placeholder="c0001234" pattern="^(0x)?[0-9a-fA-F]+$"></label>
<button id="dump_virmem" class="button" type="button" disabled>Dump virmem</button>
<button id="dump_io" class="button" type="button">Dump I/O regions</button>
<br />
<label><input type=checkbox id=update_current_function>Current function: <input type=text id=function></label>
<label>Show activities at: <input type=text id=show_act_on_viraddr placeholder="c0001234" pattern="^(0x)?[0-9a-fA-F]+$"></label>
<label>(Symbol <input type=text id=show_act_on_symbol pattern="^[a-zA-Z_][\w_]+$"></label>)</li>
<pre id="display"></pre>
</div>
<div id="tab-4" style="width: 50%">
<fieldset id="option_stopper">
<legend>
<label><input type=checkbox id=enable_stopper>Stop at</label>
</legend>
<ul style="list-style-type: none;">
<li><label>Tick: <input type=number id=stop_counter min=0></label></li>
<li><label>Instruction: <input type=text id=stop_instruction placeholder="e320f000" pattern="^(0x)?[0-9a-fA-F]+$"></label></li>
<li><label>Address: <input type=text id=stop_address placeholder="c0001234" pattern="^(0x)?[0-9a-fA-F]+$"></label>
<label>(Function <input type=text id=stop_address_name pattern="^[a-zA-Z_][\w_]+$"></label>)</li>
<li><label><input type=checkbox id=stop_at_every_branch>Every branch</label></li>
<li><label><input type=checkbox id=stop_at_every_funccall>Every function call</label></li>
</ul>
</fieldset>
<fieldset id="option_logger">
<legend>
<label><input type=checkbox id=enable_logger>Logger</label>
</legend>
<ul style="list-style-type: none;">
<li><label>Log size: <input type=number id=log_size min=0 max=10000 step=1000></label></li>
<li><label><input type=checkbox id=logger_buffering>Buffering outputs</label></li>
</ul>
</fieldset>
<fieldset id="option_tracer">
<legend>
<label><input type=checkbox id=enable_tracer>Tracer</label>
</legend>
<ul style="list-style-type: none;">
<li><label>Trace size: <input type=number id=trace_size min=0 max=10000 step=1000></label></li>
<li><label>Trace check size: <input type=number id=trace_check_size min=0 max=1000 step=5></label></li>
<li><label><input type=checkbox id=tracer_buffering>Buffering outputs</label></li>
</ul>
</fieldset>
<fieldset id="option_branch_tracer">
<legend>
<label><input type=checkbox id=enable_branch_tracer>Branch tracer</label>
</legend>
<ul style="list-style-type: none;">
<li><label>Trace size: <input type=number id=branch_trace_size min=0 max=10000 step=1000></label></li>
<li><label><input type=checkbox id=branch_tracer_buffering>Buffering outputs</label></li>
</ul>
</fieldset>
<fieldset id="option_others">
<legend>
<label>Others</label>
</legend>
<ul style="list-style-type: none;">
<li><label><input type=checkbox id=suppress_interrupts>Suppress interrupts</label></li>
<li><label><input type=checkbox id=enable_instruction_counting>Enable instruction counting</label></li>
</ul>
</fieldset>
<button id="save_options" type="button">Save</button>
</div>
</div>
</body>
</html>
================================================
FILE: css/jquery-ui-1.8.18.custom.css
================================================
/*
* jQuery UI CSS Framework 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*/
/* Layout helpers
----------------------------------*/
.ui-helper-hidden { display: none; }
.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; }
.ui-helper-clearfix:after { clear: both; }
.ui-helper-clearfix { zoom: 1; }
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
/* Interaction Cues
----------------------------------*/
.ui-state-disabled { cursor: default !important; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
/* Misc visuals
----------------------------------*/
/* Overlays */
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
/*
* jQuery UI CSS Framework 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Theming/API
*
* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
*/
/* Component containers
----------------------------------*/
.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; }
.ui-widget .ui-widget { font-size: 1em; }
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; }
.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(../images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; }
.ui-widget-content a { color: #222222; }
.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(../images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; }
.ui-widget-header a { color: #222222; }
/* Interaction states
----------------------------------*/
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(../images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; }
.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; }
.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(../images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; }
.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(../images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; }
.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; }
.ui-widget :active { outline: none; }
/* Interaction Cues
----------------------------------*/
.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; }
.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; }
.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; }
.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; }
.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
/* Icons
----------------------------------*/
/* states and images */
.ui-icon { width: 16px; height: 16px; background-image: url(../images/ui-icons_222222_256x240.png); }
.ui-widget-content .ui-icon {background-image: url(../images/ui-icons_222222_256x240.png); }
.ui-widget-header .ui-icon {background-image: url(../images/ui-icons_222222_256x240.png); }
.ui-state-default .ui-icon { background-image: url(../images/ui-icons_888888_256x240.png); }
.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(../images/ui-icons_454545_256x240.png); }
.ui-state-active .ui-icon {background-image: url(../images/ui-icons_454545_256x240.png); }
.ui-state-highlight .ui-icon {background-image: url(../images/ui-icons_2e83ff_256x240.png); }
.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui-icons_cd0a0a_256x240.png); }
/* positioning */
.ui-icon-carat-1-n { background-position: 0 0; }
.ui-icon-carat-1-ne { background-position: -16px 0; }
.ui-icon-carat-1-e { background-position: -32px 0; }
.ui-icon-carat-1-se { background-position: -48px 0; }
.ui-icon-carat-1-s { background-position: -64px 0; }
.ui-icon-carat-1-sw { background-position: -80px 0; }
.ui-icon-carat-1-w { background-position: -96px 0; }
.ui-icon-carat-1-nw { background-position: -112px 0; }
.ui-icon-carat-2-n-s { background-position: -128px 0; }
.ui-icon-carat-2-e-w { background-position: -144px 0; }
.ui-icon-triangle-1-n { background-position: 0 -16px; }
.ui-icon-triangle-1-ne { background-position: -16px -16px; }
.ui-icon-triangle-1-e { background-position: -32px -16px; }
.ui-icon-triangle-1-se { background-position: -48px -16px; }
.ui-icon-triangle-1-s { background-position: -64px -16px; }
.ui-icon-triangle-1-sw { background-position: -80px -16px; }
.ui-icon-triangle-1-w { background-position: -96px -16px; }
.ui-icon-triangle-1-nw { background-position: -112px -16px; }
.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
.ui-icon-arrow-1-n { background-position: 0 -32px; }
.ui-icon-arrow-1-ne { background-position: -16px -32px; }
.ui-icon-arrow-1-e { background-position: -32px -32px; }
.ui-icon-arrow-1-se { background-position: -48px -32px; }
.ui-icon-arrow-1-s { background-position: -64px -32px; }
.ui-icon-arrow-1-sw { background-position: -80px -32px; }
.ui-icon-arrow-1-w { background-position: -96px -32px; }
.ui-icon-arrow-1-nw { background-position: -112px -32px; }
.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
.ui-icon-arrow-4 { background-position: 0 -80px; }
.ui-icon-arrow-4-diag { background-position: -16px -80px; }
.ui-icon-extlink { background-position: -32px -80px; }
.ui-icon-newwin { background-position: -48px -80px; }
.ui-icon-refresh { background-position: -64px -80px; }
.ui-icon-shuffle { background-position: -80px -80px; }
.ui-icon-transfer-e-w { background-position: -96px -80px; }
.ui-icon-transferthick-e-w { background-position: -112px -80px; }
.ui-icon-folder-collapsed { background-position: 0 -96px; }
.ui-icon-folder-open { background-position: -16px -96px; }
.ui-icon-document { background-position: -32px -96px; }
.ui-icon-document-b { background-position: -48px -96px; }
.ui-icon-note { background-position: -64px -96px; }
.ui-icon-mail-closed { background-position: -80px -96px; }
.ui-icon-mail-open { background-position: -96px -96px; }
.ui-icon-suitcase { background-position: -112px -96px; }
.ui-icon-comment { background-position: -128px -96px; }
.ui-icon-person { background-position: -144px -96px; }
.ui-icon-print { background-position: -160px -96px; }
.ui-icon-trash { background-position: -176px -96px; }
.ui-icon-locked { background-position: -192px -96px; }
.ui-icon-unlocked { background-position: -208px -96px; }
.ui-icon-bookmark { background-position: -224px -96px; }
.ui-icon-tag { background-position: -240px -96px; }
.ui-icon-home { background-position: 0 -112px; }
.ui-icon-flag { background-position: -16px -112px; }
.ui-icon-calendar { background-position: -32px -112px; }
.ui-icon-cart { background-position: -48px -112px; }
.ui-icon-pencil { background-position: -64px -112px; }
.ui-icon-clock { background-position: -80px -112px; }
.ui-icon-disk { background-position: -96px -112px; }
.ui-icon-calculator { background-position: -112px -112px; }
.ui-icon-zoomin { background-position: -128px -112px; }
.ui-icon-zoomout { background-position: -144px -112px; }
.ui-icon-search { background-position: -160px -112px; }
.ui-icon-wrench { background-position: -176px -112px; }
.ui-icon-gear { background-position: -192px -112px; }
.ui-icon-heart { background-position: -208px -112px; }
.ui-icon-star { background-position: -224px -112px; }
.ui-icon-link { background-position: -240px -112px; }
.ui-icon-cancel { background-position: 0 -128px; }
.ui-icon-plus { background-position: -16px -128px; }
.ui-icon-plusthick { background-position: -32px -128px; }
.ui-icon-minus { background-position: -48px -128px; }
.ui-icon-minusthick { background-position: -64px -128px; }
.ui-icon-close { background-position: -80px -128px; }
.ui-icon-closethick { background-position: -96px -128px; }
.ui-icon-key { background-position: -112px -128px; }
.ui-icon-lightbulb { background-position: -128px -128px; }
.ui-icon-scissors { background-position: -144px -128px; }
.ui-icon-clipboard { background-position: -160px -128px; }
.ui-icon-copy { background-position: -176px -128px; }
.ui-icon-contact { background-position: -192px -128px; }
.ui-icon-image { background-position: -208px -128px; }
.ui-icon-video { background-position: -224px -128px; }
.ui-icon-script { background-position: -240px -128px; }
.ui-icon-alert { background-position: 0 -144px; }
.ui-icon-info { background-position: -16px -144px; }
.ui-icon-notice { background-position: -32px -144px; }
.ui-icon-help { background-position: -48px -144px; }
.ui-icon-check { background-position: -64px -144px; }
.ui-icon-bullet { background-position: -80px -144px; }
.ui-icon-radio-off { background-position: -96px -144px; }
.ui-icon-radio-on { background-position: -112px -144px; }
.ui-icon-pin-w { background-position: -128px -144px; }
.ui-icon-pin-s { background-position: -144px -144px; }
.ui-icon-play { background-position: 0 -160px; }
.ui-icon-pause { background-position: -16px -160px; }
.ui-icon-seek-next { background-position: -32px -160px; }
.ui-icon-seek-prev { background-position: -48px -160px; }
.ui-icon-seek-end { background-position: -64px -160px; }
.ui-icon-seek-start { background-position: -80px -160px; }
/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
.ui-icon-seek-first { background-position: -80px -160px; }
.ui-icon-stop { background-position: -96px -160px; }
.ui-icon-eject { background-position: -112px -160px; }
.ui-icon-volume-off { background-position: -128px -160px; }
.ui-icon-volume-on { background-position: -144px -160px; }
.ui-icon-power { background-position: 0 -176px; }
.ui-icon-signal-diag { background-position: -16px -176px; }
.ui-icon-signal { background-position: -32px -176px; }
.ui-icon-battery-0 { background-position: -48px -176px; }
.ui-icon-battery-1 { background-position: -64px -176px; }
.ui-icon-battery-2 { background-position: -80px -176px; }
.ui-icon-battery-3 { background-position: -96px -176px; }
.ui-icon-circle-plus { background-position: 0 -192px; }
.ui-icon-circle-minus { background-position: -16px -192px; }
.ui-icon-circle-close { background-position: -32px -192px; }
.ui-icon-circle-triangle-e { background-position: -48px -192px; }
.ui-icon-circle-triangle-s { background-position: -64px -192px; }
.ui-icon-circle-triangle-w { background-position: -80px -192px; }
.ui-icon-circle-triangle-n { background-position: -96px -192px; }
.ui-icon-circle-arrow-e { background-position: -112px -192px; }
.ui-icon-circle-arrow-s { background-position: -128px -192px; }
.ui-icon-circle-arrow-w { background-position: -144px -192px; }
.ui-icon-circle-arrow-n { background-position: -160px -192px; }
.ui-icon-circle-zoomin { background-position: -176px -192px; }
.ui-icon-circle-zoomout { background-position: -192px -192px; }
.ui-icon-circle-check { background-position: -208px -192px; }
.ui-icon-circlesmall-plus { background-position: 0 -208px; }
.ui-icon-circlesmall-minus { background-position: -16px -208px; }
.ui-icon-circlesmall-close { background-position: -32px -208px; }
.ui-icon-squaresmall-plus { background-position: -48px -208px; }
.ui-icon-squaresmall-minus { background-position: -64px -208px; }
.ui-icon-squaresmall-close { background-position: -80px -208px; }
.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
/* Misc visuals
----------------------------------*/
/* Corner radius */
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; }
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
/* Overlays */
.ui-widget-overlay { background: #aaaaaa url(../images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*
* jQuery UI Tabs 1.8.18
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Tabs#theming
*/
.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }
.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }
.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }
.ui-tabs .ui-tabs-hide { display: none !important; }
================================================
FILE: js/9p.js
================================================
/*!
* Javascript ARMv7 Emulator
*
* Copyright 2012, Ryota Ozaki
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
/*
* 9P2000.u Protocol
*/
function Protocol9P2000u(net9p) {
this.net9p = net9p;
this.VERSION = "9P2000.u";
this.EXTENSION = ".u";
this.IOUNIT = 4096;
this.TERROR = 106;
this.HEADER_SIZE = 4 + 1 + 2; // size + id + tag
this.msize = 0;
this.fid2qid = {};
this.path2qid = {};
}
Protocol9P2000u.prototype.hashCode32 = function(string) {
var hash = 0;
if (string.length === 0)
return hash;
for (var i=0; i < string.length; i++) {
hash = 31 * hash + string.charCodeAt(i);
hash = hash & hash;
if (hash < 0)
hash += 0x100000000;
}
return hash;
};
Protocol9P2000u.prototype.add_qid = function(fid, qid) {
//display.log("Adding fid=" + fid + ", name=" + qid.name + ", fullPath=" + qid.entry.fullPath);
this.fid2qid[fid] = qid;
this.path2qid[qid.fullPath] = qid;
};
Protocol9P2000u.prototype.del_qid = function(fid) {
var qid = this.fid2qid[fid];
delete this.fid2qid[fid];
delete this.path2qid[qid.fullPath];
};
Protocol9P2000u.prototype.get_qid = function(fid_or_path) {
if (typeof fid_or_path == "number")
return this.fid2qid[fid_or_path];
else if (typeof fid_or_path == "string")
return this.path2qid[fid_or_path];
else
abort("get_qid: unknown key type: " + (typeof fid_or_path));
};
Protocol9P2000u.prototype.build_reply = function(id, tag, payload) {
var size = this.HEADER_SIZE + payload.length;
// Reply ID is always +1 to request one
var header = this.net9p.marshal(["w", "b", "h"], [size, id + 1, tag]);
return header.concat(payload);
};
Protocol9P2000u.prototype.version = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "s"], next_data);
display.log("[version] msize=" + req[0] + ", version=" + req[1]);
this.msize = req[0];
var payload = this.net9p.marshal(["w", "s"], [this.msize, this.VERSION]);
return this.build_reply(id, tag, payload);
};
Protocol9P2000u.prototype[100] = Protocol9P2000u.prototype.version;
Protocol9P2000u.prototype.attach = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "w", "s", "s", "w"], next_data);
var fid = req[0];
var afid = req[1]; // For auth. Ignored.
var uname = req[2]; // Username. Ignored.
var aname = req[3]; // Mount point. Ignored.
var n_uname = req[4];
display.log("[attach] fid=" + fid + ", afid=" + afid + ", uname=" + uname
+ ", aname=" + aname + ", n_uname=" + n_uname);
// Return root directory's QID
var net9p = this.net9p;
var that = this;
net9p.fs.getRoot(function(entry) {
var qid = {
type: 0x10 | 0x80, // mount point & directory
version: entry.mtime.getTime(),
path: that.hashCode32(entry.fullPath),
name: "/",
entry: entry, // It includes fullPath and mtime
atime: getCurrentTime(), // Need to update
parent: null // See below
};
qid.parent = qid; // To avoid checking null
display.log("[attach] fullPath=" + entry.fullPath);
that.add_qid(fid, qid);
var payload = net9p.marshal(["Q"], [qid]);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
return null;
};
Protocol9P2000u.prototype[104] = Protocol9P2000u.prototype.attach;
Protocol9P2000u.prototype.walk = function(id, tag, next_data) {
// path elements ["root", "dir1", "dir2",...]
var req = this.net9p.unmarshal(["w", "w", "h"], next_data);
var fid = req[0];
var nwfid = req[1];
var nwname = req[2];
display.log("[walk] fid=" + fid + ", nwfid=" + nwfid + ", nwname=" + nwname);
var qid = this.get_qid(fid);
if (!qid)
abort("No such QID found for fid=" + fid);
if (nwname === 0) {
this.add_qid(nwfid, qid);
var payload = this.net9p.marshal(["h"], [0]);
return this.build_reply(id, tag, payload);
}
var wnames = [];
for (var i=0; i < nwname; i++) {
wnames.push(this.net9p.unmarshal(["s"], next_data));
}
display.log("[walk] wnames=[" + wnames.toString() + "]");
display.log("[walk] path=" + qid.entry.fullPath);
ret_qids = [];
var net9p = this.net9p;
var that = this;
var walk = function(pqid, names) {
var name = names[0];
if (name) {
display.log("[walk] walking: " + name);
net9p.fs.getEntry(pqid.entry, name, function(entry) {
var _qid = {
type: (entry.isDirectory ? 0x80 : 0),
version: entry.mtime.getTime(),
path: that.hashCode32(entry.fullPath),
name: entry.name,
entry: entry,
atime: (entry.isDirectory ? getCurrentTime() : entry.mtime.getTime()),
parent: pqid
};
ret_qids.push(_qid);
walk(_qid, names.slice(1));
}, function(e) {
if (names == wnames) {
// FIXME: have to check error code
var payload = net9p.marshal(["s", "w"], ["No such file or directory", 2]);
var reply = that.build_reply(that.TERROR, tag, payload);
} else {
// Return walked QIDs
var types = ["h"];
var data = [ret_qids.length];
for (var i in ret_qids) {
types.push("Q");
types.push(ret_qids[i]);
}
var payload = net9p.marshal(types, data);
var reply = that.build_reply(id, tag, payload);
}
net9p.send_reply(reply);
});
} else {
// Walked sucessfully
that.add_qid(nwfid, ret_qids[ret_qids.length - 1]);
// Return walked QIDs
var types = ["h"];
var data = [ret_qids.length];
for (var i in ret_qids) {
types.push("Q");
data.push(ret_qids[i]);
}
var payload = net9p.marshal(types, data);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
}
};
walk(qid, wnames);
return null;
};
Protocol9P2000u.prototype[110] = Protocol9P2000u.prototype.walk;
Protocol9P2000u.prototype.open = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "b"], next_data);
var fid = req[0];
var mode = req[1];
display.log("[open] fid=" + fid + ", mode=" + mode.toString(16));
var qid = this.get_qid(fid);
if (!qid)
abort("[open] No such QID found for fid=" + fid);
if (mode & 0x10) {
var net9p = this.net9p;
var that = this;
net9p.fs.truncate(qid.entry, function(entry) {
// Update
qid.entry = entry;
qid.version = entry.mtime.getTime();
qid.atime = getCurrentTime();
var payload = net9p.marshal(["Q", "w"], [qid, this.IOUNIT]);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
return null;
} else {
var payload = this.net9p.marshal(["Q", "w"], [qid, this.IOUNIT]);
return this.build_reply(id, tag, payload);
}
};
Protocol9P2000u.prototype[112] = Protocol9P2000u.prototype.open;
Protocol9P2000u.prototype.create = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "s", "w", "b", "s"], next_data);
var fid = req[0];
var name = req[1];
var perm = req[2];
var mode = req[3];
var extension = req[4];
display.log("[create] fid=" + fid + ", name=" + name + ", perm=" + perm.toString(16)
+ ", mode=" + mode.toString(2) + ", extension=" + extension);
var qid = this.get_qid(fid);
if (!qid)
abort("[create] No such QID found for fid=" + fid);
var net9p = this.net9p;
var that = this;
var isfile = perm & 0x80000000 ? false : true;
net9p.fs.create(qid.entry, name, {file: isfile}, function(entry) {
display.log("[create] fullPath=" + entry.fullPath);
var cqid = {
type: isfile ? 0 : 0x80,
version: entry.mtime.getTime(),
path: that.hashCode32(entry.fullPath),
name: entry.name,
entry: entry,
atime: isfile ? entry.mtime.getTime() : getCurrentTime(),
parent: qid
};
that.add_qid(fid, cqid);
qid.parent.atime = getCurrentTime(); // FIXME: different from entry.mtime
var payload = net9p.marshal(["Q", "w"], [cqid, that.IOUNIT]);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
return null;
};
Protocol9P2000u.prototype[114] = Protocol9P2000u.prototype.create;
Protocol9P2000u.prototype.read_directory = function(qid, offset, entries) {
var atime = qid.atime;
var mtime = qid.entry.mtime.getTime();
var data = this.build_stat(".", 0, qid, atime, mtime);
atime = qid.parent.atime;
mtime = qid.parent.entry.mtime.getTime();
data = data.concat(this.build_stat("..", 0, qid.parent, atime, mtime));
for (var i in entries) {
var ent = entries[i];
display.log("[read] name=" + ent.name);
var cqid = this.get_qid(ent.fullPath);
mtime = ent.mtime.getTime();
if (!cqid) {
cqid = {
type: (ent.isDirectory ? 0x80 : 0),
version: mtime,
path: this.hashCode32(ent.fullPath)
};
}
var stat = this.build_stat(ent.name, ent.size, cqid, atime, mtime);
data = data.concat(stat);
}
if (offset)
data = data.slice(offset);
var count = this.net9p.marshal(["w"], [data.length]);
display.log("[read] count=" + data.length);
return count.concat(data);
};
Protocol9P2000u.prototype.read = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "w", "w", "w"], next_data);
var fid = req[0];
var offset = req[1];
//var offset = req[2]; // FIXME
var count = req[3];
display.log("[read] fid=" + fid + ", offset=" + offset + ", count=" + count);
var qid = this.get_qid(fid);
if (!qid)
abort("[read] No such QID found for fid=" + fid);
var net9p = this.net9p;
var that = this;
if (qid.type & 0x80) { // directory
display.log("[read] reading directory: " + qid.entry.fullPath);
net9p.fs.getDirectoryEntries(qid.entry, function(entries) {
qid.atime = getCurrentTime();
var payload = that.read_directory(qid, offset, entries);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
} else { // file
net9p.fs.read(qid.entry, offset, count, function(data) {
qid.atime = getCurrentTime();
var count = net9p.marshal(["w"], [data.length]);
display.log("[read] count=" + data.length);
var payload = count.concat(data);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
}
return null;
};
Protocol9P2000u.prototype[116] = Protocol9P2000u.prototype.read;
Protocol9P2000u.prototype.write = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w", "w", "w", "w"], next_data);
var fid = req[0];
var offset = req[1];
//var offset = req[2];
var count = req[3];
var qid = this.get_qid(fid);
if (!qid)
abort("[write] No such QID found for fid=" + fid);
display.log("[write] fid=" + fid + ", offset=" + offset
+ ", count=" + count + ", fullPath=" + qid.entry.path);
var buffer = new ArrayBuffer(count);
var data = new Uint8Array(buffer, 0, count);
for (var i=0; i < count; i++)
data[i] = next_data();
var net9p = this.net9p;
var that = this;
net9p.fs.write(qid.entry, buffer, offset, function(entry) {
qid.entry = entry;
qid.atime = getCurrentTime();
var payload = net9p.marshal(["w"], [data.byteLength]);
display.log("[write] count=" + data.byteLength);
var reply = that.build_reply(id, tag, payload);
net9p.send_reply(reply);
});
return null;
};
Protocol9P2000u.prototype[118] = Protocol9P2000u.prototype.write;
Protocol9P2000u.prototype.clunk = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w"], next_data);
var fid = req[0];
display.log("[clunk] fid=" + fid);
this.del_qid(fid);
return this.build_reply(id, tag, []);
};
Protocol9P2000u.prototype[120] = Protocol9P2000u.prototype.clunk;
Protocol9P2000u.prototype.remove = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w"], next_data);
var fid = req[0];
var qid = this.get_qid(fid);
if (!qid)
abort("[remove] No such QID found for fid=" + fid);
display.log("[remove] fid=" + fid);
var net9p = this.net9p;
var that = this;
net9p.fs.remove(qid.entry, function() {
// clunk fid as well
that.del_qid(fid);
qid.parent.atime = getCurrentTime(); // FIXME: different from entry.mtime
var reply = that.build_reply(id, tag, []);
net9p.send_reply(reply);
});
return null;
};
Protocol9P2000u.prototype[122] = Protocol9P2000u.prototype.remove;
Protocol9P2000u.prototype.build_stat = function(name, filesize, qid, atime, mtime) {
//display.log("qid.type=" + qid.type.toString(16));
var types = [
"h", // size
"h", // type
"w", // dev
"Q", // qid
"w", // mode
"w", // atime
"w", // mtime
"w", // length0
"w", // length1
"s", // name
"s", // uid
"s", // gid
"s", // muid
"s", // extension
"w", // n_uid
"w", // n_gid
"w" // n_muid
];
var data = [
0, // size
0, // type
0, // dev
qid, // qid
(qid.type & 0x80) ? (0x80000000 | 0755) : 0644, // mode
atime, // atime
mtime, // mtime
filesize, // length0 FIXME
0, // length1
name, // name
"root", // uid
"root", // gid
"root", // muid
".u", // extension
0, // n_uid
0, // n_guid
0 // n_muid
];
var stat = this.net9p.marshal(types, data);
// Fill size
stat[0] = (stat.length - 2) & 0xff;
stat[1] = (stat.length - 2) >>> 8;
return stat;
};
Protocol9P2000u.prototype.build_stat_vals_from_data = function(data) {
var types = [
"h", // size
"h", // type
"w", // dev
"Q", // qid
"w", // mode
"w", // atime
"w", // mtime
"w", // length0
"w", // length1
"s", // name
"s", // uid
"s", // gid
"s", // muid
"s", // extension
"w", // n_uid
"w", // n_gid
"w" // n_muid
];
var stat_vals = this.net9p.unmarshal(types, data);
return stat_vals;
};
Protocol9P2000u.prototype.stat = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w"], next_data);
var fid = req[0];
var qid = this.get_qid(fid);
if (!qid)
abort("[stat] No such QID found for fid=" + fid);
display.log("[stat] path=" + qid.entry.fullPath);
var filesize = qid.entry.isDirectory ? 0 : qid.entry.size;
var payload = this.build_stat(qid.name, filesize, qid, qid.atime, qid.entry.mtime.getTime());
payload = [0, 0].concat(payload); // Ignored by guest but required
var reply = this.build_reply(id, tag, payload);
return reply;
};
Protocol9P2000u.prototype[124] = Protocol9P2000u.prototype.stat;
Protocol9P2000u.prototype.wstat = function(id, tag, next_data) {
var req = this.net9p.unmarshal(["w"], next_data);
var fid = req[0];
next_data(); next_data(); // We need it to remove unknown halfword data
var stat_vals = this.build_stat_vals_from_data(next_data);
var qid = this.get_qid(fid);
if (!qid)
abort("[wstat] No such QID found for fid=" + fid);
display.log("[wstat] path=" + qid.entry.fullPath);
qid.atime = qid.parent.atime = getCurrentTime();
if (stat_vals[9] && stat_vals[9] != qid.name) {
var newname = stat_vals[9];
// FIXME: support only rename
display.log("[wstat] newname=" + newname + ", name=" + name);
var net9p = this.net9p;
var that = this;
display.log("[wstat] parent=" + qid.parent.entry.fullPath);
net9p.fs.rename(qid.parent.entry, qid.name, newname, function(entry) {
var reply = that.build_reply(id, tag, []);
net9p.send_reply(reply);
});
return null;
} else {
return this.build_reply(id, tag, []);
}
};
Protocol9P2000u.prototype[126] = Protocol9P2000u.prototype.wstat;
function Net9p(virtio) {
this.virtio = virtio;
this.proto = new Protocol9P2000u(this);
this.fs = new HTML5FileSystem('/9proot', 50 * 1024 * 1024);
}
Net9p.prototype.marshal = function(type, data) {
var out = [];
var item;
for (var i=0; i < type.length; i++) {
item = data[i];
switch (type[i]) {
case "w":
out.push(item & 0xff);
out.push((item >>> 8) & 0xff);
out.push((item >>> 16) & 0xff);
out.push(item >>> 24);
break;
case "h":
out.push(item & 0xff);
out.push(item >>> 8);
break;
case "b":
out.push(item);
break;
case "s":
// Prepend size
out.push(item.length & 0xff);
out.push(item.length >>> 8);
for (var j in item)
out.push(item.charCodeAt(j));
break;
case "D":
for (var j in item)
out.push(item[j]);
break;
case "Q":
out = out.concat(this.marshal(["b"], item.type));
out = out.concat(this.marshal(["w"], item.version));
out = out.concat(this.marshal(["w"], item.path));
out = out.concat(this.marshal(["w"], 0)); // FIXME
break;
default:
abort("marshal: Unknown type=" + type[i]);
}
}
return out;
};
Net9p.prototype.unmarshal = function(type, data_or_generator) {
var out = [];
var get = (typeof data_or_generator == "function") ?
data_or_generator :
function() { return data_or_generator.shift(); };
for (var i=0; i < type.length; i++) {
switch (type[i]) {
case "w":
var val = get();
val += get() << 8;
val += get() << 16;
var tmp = get() << 24;
if (tmp < 0)
tmp += 0x100000000;
out.push(val + tmp);
break;
case "h":
var val = get();
out.push(val + (get() << 8));
break;
case "b":
out.push(get());
break;
case "s":
var len = get();
len += get() << 8;
var str = '';
for (var j=0; j < len; j++)
str += String.fromCharCode(get());
out.push(str);
break;
case "Q":
var stat = {
type: 0,
version: 0,
path: 0
};
stat.type = this.unmarshal(["b"], get)[0];
stat.version = this.unmarshal(["w"], get)[0];
stat.path = this.unmarshal(["w", "w"], get)[0]; // FIXME
out.push(stat);
break;
default:
abort("unmarshal: Unknown type=" + type[i]);
}
}
return out;
};
Net9p.prototype.get_header_size = function() {
return this.proto.HEADER_SIZE;
};
Net9p.prototype.get_body_size = function(id) {
return this.proto.HEADER_SIZE;
};
Net9p.prototype.unmarshal_header = function(data) {
var header = this.unmarshal(["w", "b", "h"], data);
return {
size: header[0],
id: header[1],
tag: header[2]
};
};
Net9p.prototype.send_reply = function(reply) {
this.virtio.send_reply(reply);
};
================================================
FILE: js/JSONlocalStorage.js
================================================
/*!
* Javascript ARMv7 Emulator
*
* Copyright 2012, Ryota Ozaki
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
function JSONlocalStorage(name, target, list) {
this.name = name;
this.target = target;
this.list = list;
}
JSONlocalStorage.prototype.restore = function() {
var json = localStorage[this.name];
if (!json)
return;
var data = JSON.parse(json);
for (var i in this.list) {
var name = this.list[i];
var val = data[name];
if (val || val === false) {
//console.debug("localStorage[" + opt + "] => " + val);
this.target[name] = val;
}
}
};
JSONlocalStorage.prototype.save = function() {
var data = Object();
//localStorage.clear();
for (var i in this.list) {
var name = this.list[i];
var val = this.target[name];
if (val || val === false) {
//console.debug("localStorage[" + opt + "] <= " + val);
data[name] = val;
}
}
localStorage[this.name] = JSON.stringify(data);
};
================================================
FILE: js/armv7-cp15.js
================================================
/*!
* Javascript ARMv7 Emulator
*
* Copyright 2012, Ryota Ozaki
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
/*
* CP15 System Control Coprocessor
*/
function ARMv7_CP15(options, cpu) {
this.options = options;
this.cpu = cpu;
this.interrupt_vector_address = 0;
this.read = new Object();
this.write = new Object();
this.data = new Object();
this.TRANS_FAULT_SECTION = 5; // 0b00101
this.TRANS_FAULT_PAGE = 7; // 0b00111
this.PERMISSION_FAULT_SECTION = 0xd; // 0b01101
this.PERMISSION_FAULT_PAGE = 0xf; // 0b01111
// crn, opc1, crm, opc2
this.MIDR = [0, 0, 0, 0];
this.CTR = [0, 0, 0, 1];
this.ID_PFR0 = [0, 0, 1, 0];
this.ID_MMFR0 = [0, 0, 1, 4];
this.ID_MMFR1 = [0, 0, 1, 5];
this.ID_ISAR0 = [0, 0, 2, 0];
this.CCSIDR = [0, 1, 0, 0];
this.CLIDR = [0, 1, 0, 1];
this.CSSELR = [0, 2, 0, 0];
this.SCTLR = [1, 0, 0, 0];
this.CPACR = [1, 0, 0, 2];
this.TTBR0 = [2, 0, 0, 0];
this.TTBR1 = [2, 0, 0, 1];
this.TTBCR = [2, 0, 0, 2];
this.ICIALLU = [7, 0, 5, 0];
this.ICIMVAU = [7, 0, 5, 1];
this.BPIALL = [7, 0, 5, 6];
this.BPIMVA = [7, 0, 5, 7];
this.ISB = [7, 0, 5, 4];
this.DCCMVAC = [7, 0,10, 1];
this.DSB = [7, 0,10, 4];
this.DMB = [7, 0,10, 5];
this.DCCMVAU = [7, 0,11, 1];
this.DCCIMVAC = [7, 0,14, 1];
this.DACR = [3, 0, 0, 0];
this.DFSR = [5, 0, 0, 0];
this.IFSR = [5, 0, 0, 1]; // Instruction Fault Status Register (IFSR)
this.DFAR = [6, 0, 0, 0]; // Data Fault Address Register (DFAR)
this.IFAR = [6, 0, 0, 2]; // Instruction Fault Address Register (IFAR)
this.ITLBIALL = [8, 0, 5, 0];
this.ITLBIMVA = [8, 0, 5, 1];
this.ITLBIASID = [8, 0, 5, 2];
this.DTLBIALL = [8, 0, 6, 0];
this.DTLBIMVA = [8, 0, 6, 1];
this.DTLBIASID = [8, 0, 6, 2];
this.UTLBIALL = [8, 0, 7, 0];
this.UTLBIMVA = [8, 0, 7, 1];
this.UTLBIASID = [8, 0, 7, 2];
this.PRRR = [10, 0, 2, 0]; // c10, Primary Region Remap Register (PRRR)
this.NMRR = [10, 0, 2, 1]; // c10, Normal Memory Remap Register (NMRR)
this.CONTEXTIDR = [13, 0, 0, 1];
this.TPIDRURW = [13, 0, 0, 2]; // User Read/Write Thread ID Register, TPIDRURW
this.TPIDRURO = [13, 0, 0, 3]; // User Read-only Thread ID Register, TPIDRURO
var mmu = this.cpu.mmu;
var that = this;
// [31:24]=Implementor [23:20]=Variant [19:16]=Architecture [15:4]=Primary part number [3:0]=Revision
// MRC p15,0,<Rd>,c0,c0,0 ; Read CP15 Main ID Register
var midr = 0;
midr = bitops.set_bits(midr, 31, 24, 0x41); // ARM Limited
midr = bitops.set_bits(midr, 23, 20, 0x1); // Major Revison Number
midr = bitops.set_bits(midr, 19, 16, 0xf); // Defined by CPUID scheme
// [15:12] != 0x0 and != 0x7
midr = bitops.set_bits(midr, 15, 12, 0xf);
midr = bitops.set_bits(midr, 3, 0, 0x1); // Minor Revison Number
this.register_readonly("MIDR", midr);
/*
* CTR: Cache Type Register
* Bits [31:29]: Set to 0b100 for the ARMv7 register format.
* CWG, bits [27:24]: Cache Writeback Granule
* ERG, bits [23:20]: Exclusives Reservation Granule // Manual is wrong :-)
* DminLine, bits [19:16]: Log2 of the number of words in the smallest cache line of all the data caches and unified caches that are controlled by the core.
* L1Ip, bits [15:14]: Level 1 instruction cache policy.
* IminLine, bits [3:0]: Log2 of the number of words in the smallest cache line of all the instruction caches that are controlled by the core.
*/
var ctr = 0;
ctr = bitops.set_bits(ctr, 31, 29, 4);
ctr = bitops.set_bits(ctr, 27, 24, 0);
ctr = bitops.set_bits(ctr, 23, 20, 0);
ctr = bitops.set_bits(ctr, 19, 16, 0); // FIXME
ctr = bitops.set_bits(ctr, 15, 14, 1); // ASID-tagged Virtual Index, Virtual Tag (AIVIVT)
ctr = bitops.set_bits(ctr, 3, 0, 0); // FIXME
this.register_readonly("CTR", ctr);
// TODO
var sctlr = 0;
sctlr = bitops.set_bit(sctlr, 31, 0); // UNK/SBZP
sctlr = bitops.set_bit(sctlr, 30, 0); // TE: Thumb Exception enable
sctlr = bitops.set_bit(sctlr, 29, 0); // AFE: Access Flag Enable bit
sctlr = bitops.set_bit(sctlr, 28, 0); // TRE: TEX Remap Enable bit
sctlr = bitops.set_bit(sctlr, 27, 0); // NMFI: Non-maskable Fast Interrupts enable
sctlr = bitops.set_bit(sctlr, 25, 0); // EE: Exception Endianness bit
sctlr = bitops.set_bit(sctlr, 24, 0); // VE: Interrupt Vectors Enable bit
sctlr = bitops.set_bit(sctlr, 22, 1); // U: In ARMv7 this bit is RAO/SBOP
sctlr = bitops.set_bit(sctlr, 21, 0); // FI: Fast Interrupts configuration enable bit
sctlr = bitops.set_bit(sctlr, 17, 0); // HA: Hardware Access Flag Enable bit
sctlr = bitops.set_bit(sctlr, 14, 0); // RR: Round Robin bit
sctlr = bitops.set_bit(sctlr, 13, 0); // V: Vectors bit
sctlr = bitops.set_bit(sctlr, 12, 0); // I: Instruction cache enable bit
sctlr = bitops.set_bit(sctlr, 11, 0); // Z: Branch prediction enable bit
sctlr = bitops.set_bit(sctlr, 7, 0); // B: In ARMv7 this bit is RAZ/SBZP
sctlr = bitops.set_bit(sctlr, 2, 0); // C: Cache enable bit
sctlr = bitops.set_bit(sctlr, 1, 0); // A: Alignment bit
sctlr = bitops.set_bit(sctlr, 0, 0); // M: MMU enable bit
this.register_writable("SCTLR", sctlr, function (word) {
that.data["SCTLR"] = word;
if (word & 1) {
mmu.enabled = true;
} else {
mmu.enabled = false;
}
if (!(word & 0x01000000)) { // SCTLR.VE[24]
if (word & 0x00002000) { // SCTLR.V[13]
that.interrupt_vector_address = 0xffff0000;
} else {
that.interrupt_vector_address = 0x00000000;
}
}
if (word & 2) {// SCTLR.A[1]
mmu.check_unaligned = true;
throw "Check unaligned access!";
} else {
mmu.check_unaligned = false;
}
// Always 1
that.data["SCTLR"] = bitops.set_bit(that.data["SCTLR"], 22, 1);
});
var id_pfr0 = 0;
id_pfr0 = bitops.set_bits(id_pfr0, 3, 0, 1); // ARM instruction set supported
this.register_readonly("ID_PFR0", id_pfr0);
var id_mmfr0 = 0;
id_mmfr0 = bitops.set_bits(id_mmfr0, 31, 28, 0); // Reserved, Read-As-Zero
id_mmfr0 = bitops.set_bits(id_mmfr0, 37, 24, 0); // FCSE support
id_mmfr0 = bitops.set_bits(id_mmfr0, 23, 20, 0); // Auxiliary registers
// ARMv7 requires this setting.
id_mmfr0 = bitops.set_bits(id_mmfr0, 19, 16, 1); // TCM support
id_mmfr0 = bitops.set_bits(id_mmfr0, 15, 12, 0); // Outer Shareable
id_mmfr0 = bitops.set_bits(id_mmfr0, 11, 8, 0); // Cache coherence
id_mmfr0 = bitops.set_bits(id_mmfr0, 7, 4, 0); // PMSA support
// VMSAv7 supported, with support for remapping and the access flag. ARMv7-A profile.
id_mmfr0 = bitops.set_bits(id_mmfr0, 3, 0, 3); // VMSA support
this.register_readonly("ID_MMFR0", id_mmfr0);
var id_isar0 = 0;
this.register_readonly("ID_ISAR0", id_mmfr0);
var id_mmfr1 = 0;
// For execution correctness, Branch Predictor requires no flushing at any time.
id_mmfr1 = bitops.set_bits(id_mmfr1, 31, 28, 4); // Branch Predictor
// None supported. This is the required setting for ARMv7.
id_mmfr1 = bitops.set_bits(id_mmfr1, 37, 24, 0); // L1 cache Test and Clean
// None supported. This is the required setting for ARMv7, because ARMv7 requires a hierarchical cache implementation.
id_mmfr1 = bitops.set_bits(id_mmfr1, 23, 20, 0); // L1 unified cache
id_mmfr1 = bitops.set_bits(id_mmfr1, 19, 16, 0); // L1 Harvard cache
id_mmfr1 = bitops.set_bits(id_mmfr1, 15, 12, 0); // L1 unified cache s/w
id_mmfr1 = bitops.set_bits(id_mmfr1, 11, 8, 0); // L1 Harvard cache s/w
id_mmfr1 = bitops.set_bits(id_mmfr1, 7, 4, 0); // L1 unified cache VA
id_mmfr1 = bitops.set_bits(id_mmfr1, 3, 0, 0); // L1 Harvard cache VA
this.register_readonly("ID_MMFR1", id_mmfr1);
// c0, Cache Size ID Registers (CCSIDR)
/*
* WT, bit [31]: Indicates whether the cache level supports Write-Through
* WB, bit [30]: Indicates whether the cache level supports Write-Back
* RA, bit [29]: Indicates whether the cache level supports Read-Allocation
* WA, bit [28]: Indicates whether the cache level supports Write-Allocation
* NumSets, bits [27:13]: Number of sets in cache
* Associativity, bits [12:3]: Associativity of cache
* LineSize, bits [2:0]: Log2(Number of words in cache line)
*/
var ccsidr = 0;
ccsidr = bitops.set_bit(ccsidr, 31, 1);
ccsidr = bitops.set_bit(ccsidr, 30, 1);
ccsidr = bitops.set_bit(ccsidr, 29, 1);
ccsidr = bitops.set_bit(ccsidr, 28, 1);
ccsidr = bitops.set_bits(ccsidr, 27, 13, 0); // One set
ccsidr = bitops.set_bits(ccsidr, 12, 3, 1); // Two set associative
ccsidr = bitops.set_bits(ccsidr, 2, 0, 0); // 4 words length
this.register_readonly("CCSIDR", ccsidr);
// Cache Level ID Register
var clidr = 0;
clidr = bitops.set_bits(clidr, 29, 27, 0); // LoU: Level of Unification for the cache hierarchy
clidr = bitops.set_bits(clidr, 26, 24, 0); // LoC: Level of Coherency for the cache hierarchy
clidr = bitops.set_bits(clidr, 23, 21, 0); // Ctype8
clidr = bitops.set_bits(clidr, 20, 18, 0); // Ctype7
clidr = bitops.set_bits(clidr, 17, 15, 0); // Ctype6
clidr = bitops.set_bits(clidr, 14, 12, 0); // Ctype5
clidr = bitops.set_bits(clidr, 11, 9, 0); // Ctype4
clidr = bitops.set_bits(clidr, 8, 6, 0); // Ctype3
clidr = bitops.set_bits(clidr, 5, 3, 0); // Ctype2
clidr = bitops.set_bits(clidr, 2, 0, 0); // Ctype1
this.register_readonly("CLIDR", clidr);
// CSSELR, Cache Size Selection Register
var csselr = 0;
csselr = bitops.set_bits(csselr, 3, 1, 0); // Level: Cache level of required cache
csselr = bitops.set_bit(csselr, 0, 0); // InD: Instruction not Data bit
this.register_writable("CSSELR", csselr);
/*
* Translation Table Base Register 0 (TTBR0)
* bits[31:14-N]: Translation table base 0 address
* bit[5]: NOS: Not Outer Shareable bit
* bits[4:3]: RGN: Region bits
* bit[2]: IMP: Implementation defined bit
* bit[1]: S: Shareable bit
* bit[0]: C: Cacheable bit
*/
this.register_writable("TTBR0", 0, function (word) {
display.log("TTBR0");
that.data["TTBR0"] = word;
mmu.baseaddr0 = bitops.clear_bits(word, 13 - mmu.width, 0);
if (that.options.enable_logger) {
that.log_value(word, "ttbr0");
that.log_value(mmu.baseaddr0, "baseaddr0 in ttbr0");
}
});
/*
* Translation Table Base Register 1 (TTBR1)
* bits[31:14]: Translation table base 1 address
* bit[5]: NOS: Not Outer Shareable bit
* bits[4:3]: RGN: Region bits
* bit[2]: IMP: Implementation defined bit
* bit[1]: S: Shareable bit
* bit[0]: C: Cacheable bit
*/
this.register_writable("TTBR1", 0, function (word) {
display.log("TTBR1");
that.data["TTBR1"] = word;
mmu.baseaddr1 = bitops.clear_bits(word, 13, 0);
if (that.options.enable_logger) {
that.log_value(word, "ttbr1");
that.log_value(mmu.baseaddr1, "baseaddr1 in ttbr1");
}
});
/*
* Translation Table Base Control Register (TTBCR)
* bits[2:0]: N: Indicate the width of the base address held in TTBR0
*/
this.register_writable("TTBCR", 0, function(word) {
display.log("TTBCR");
that.data["TTBCR"] = word;
var width = bitops.get_bits(word, 2, 0);
var ttbr0 = that.data["TTBR0"];
mmu.width = width;
mmu.mask = (1 << (31 - width - 20 + 1)) - 1;
mmu.baseaddr0 = bitops.clear_bits(ttbr0, 13 - width, 0);
that.log_value(word, "word");
that.log_value(mmu.baseaddr0, "baseaddr0 in ttbcr");
if (width) {
throw "width > 0";
var ttbr1 = that.data["TTBR1"];
mmu.baseaddr1 = bitops.clear_bits(ttbr1, 13, 0);
that.log_value(word, "word");
that.log_value(mmu.baseaddr1, "baseaddr1 in ttbcr");
}
display.log("TTBCR called.");
});
/*
* CPACR, Coprocessor Access Control Register
*/
this.register_writable("CPACR", 0);
/*
* Domain Access Control Register (DACR)
* bits[31:30]: D15
* ...
* bits[1:0]: D0
* 00: No access. Any access to the domain generates a Domain fault.
* 01: Client. Accesses are checked against the permission bits in the translation tables.
* 10: Reserved, effect is UNPREDICTABLE
* 11: Manager. Accesses are not checked against the permission bits in the translation tables.
*/
var dacr = 0;
this.domains = new Array();
for (var i=0; i < 16; i++)
this.domains[i] = 0;
this.register_writable("DACR", dacr, function (word) {
that.data["DACR"] = word;
for (var i=0; i < 16; i++) {
that.domains[i] = bitops.get_bits(word, i*2+1, i*2);
}
});
/*
* Data Fault Status Register (DFSR)
* bit[12]: ExT, External abort type
* bit[11]: WnR, Write not Read
* bits[10,3:0]: FS, Fault status
* //bits[7:4]: Domain, The domain of the fault address
*/
// Note that these registers are actually read-only POV of software,
// however, the values are changed by hardware during memory abort.
// To be save/restore-able, register them as writable.
this.register_writable("DFAR", 0);
this.register_writable("IFAR", 0);
this.register_writable("DFSR", 0);
this.register_writable("IFSR", 0);
this.register_writeonly("ICIALLU");
this.register_writeonly("ICIMVAU");
this.register_writeonly("BPIALL");
this.register_writeonly("BPIMVA");
this.register_writeonly("ISB"); // Instruction Synchronization Barrier
this.register_writeonly("DCCMVAC"); // Clean data cache linux by MVA to PoU
this.register_writeonly("DSB"); // Data Synchronization Barrier
this.register_writeonly("DMB"); // Data Memory Barrier
this.register_writeonly("DCCMVAU"); // Clean data cache line by MVA to PoU
this.register_writeonly("DCCIMVAC"); // Clean and invalidate data cache line by MVA to PoU
this.register_writeonly("ITLBIALL"); // invalidate instruction TLB
this.register_writeonly("ITLBIMVA"); // invalidate instruction TLB entry by MVA
this.register_writeonly("ITLBIASID"); // invalidate instruction TLB by ASID match
this.register_writeonly("DTLBIALL"); // invalidate data TLB
this.register_writeonly("DTLBIMVA"); // invalidate data TLB entry by MVA
this.register_writeonly("DTLBIASID"); // invalidate data TLB by ASID match
this.register_writeonly("UTLBIALL"); // invalidate unified TLB
this.register_writeonly("UTLBIMVA"); // invalidate unified TLB entry by MVA
this.register_writeonly("UTLBIASID");
this.register_writable("PRRR", 0); // TODO
this.register_writable("NMRR", 0); // TODO
// Context ID Register (CONTEXTIDR)
this.register_writable("CONTEXTIDR", 0, function (word) {
var procid = (word >>> 8) & 0x00ffffff;
var asid = word & 0xff;
var old_asid = that.data["CONTEXTIDR"] & 0xff;
display.log("PROCID=" + procid + ", ASID=" + asid + ", ASID(old)=" + old_asid);
mmu.asid = asid;
that.data["CONTEXTIDR"] = word;
});
// Software Thread ID registers
this.register_writable("TPIDRURW", 0);
this.register_writable("TPIDRURO", 0);
}
ARMv7_CP15.prototype.register_readonly = function(name, initval) {
this.read[this[name]] = initval;
};
ARMv7_CP15.prototype.register_writeonly = function(name, cb_w) {
if (cb_w) {
this.write[this[name]] = cb_w;
} else {
var that = this;
this.write[this[name]] = function(word) {
that.data[name] = word;
};
}
};
ARMv7_CP15.prototype.register_writable = function(name, initval, cb_w) {
this.data[name] = initval;
var that = this;
if (cb_w) {
this.read[this[name]] = function() {
return that.data[name];
};
this.write[this[name]] = cb_w;
} else {
this.read[this[name]] = function() {
return that.data[name];
};
this.write[this[name]] = function(word) {
that.data[name] = word;
};
}
};
ARMv7_CP15.prototype.send_word = function(inst, word) {
var opc1 = (inst >>> 21) & 0x7;
var crn = (inst >>> 16) & 0xf; // the major register specifier
var opc2 = (inst >>> 5) & 0x7;
var crm = inst & 0xf;
var func = this.write[[crn, opc1, crm, opc2]];
if (func)
func(word);
else
throw "write: " + [crn, opc1, crm, opc2];
};
ARMv7_CP15.prototype.get_word = function(inst) {
var opc1 = (inst >>> 21) & 0x7;
var crn = (inst >>> 16) & 0xf; // the major register specifier
var opc2 = (inst >>> 5) & 0x7;
var crm = inst & 0xf;
//this.dump_inst(inst);
var ret = this.read[[crn, opc1, crm, opc2]];
if (typeof ret == "number")
return ret;
else if (ret !== undefined)
return ret();
else
throw "read: " + [crn, opc1, crm, opc2];
};
ARMv7_CP15.prototype.save = function() {
var params = Object();
for (var i in this.data) {
params[i] = this.data[i];
}
return params;
};
ARMv7_CP15.prototype.restore = function(params) {
for (var i in this.data) {
this.data[i] = params[i];
}
if (bitops.get_bit(this.data["SCTLR"], 0))
this.cpu.mmu.enabled = true;
else
this.cpu.mmu.enabled = false;
if (!bitops.get_bit(this.data["SCTLR"], 24)) { // SCTLR.VE
if (bitops.get_bit(this.data["SCTLR"], 13)) { // SCTLR.V
this.interrupt_vector_address = 0xffff0000;
} else {
this.interrupt_vector_address = 0x00000000;
}
}
if (bitops.get_bit(this.data["SCTLR"], 1)) // SCTLR.A
this.cpu.mmu.check_unaligned = true;
else
this.cpu.mmu.check_unaligned = false;
for (var i=0; i < 16; i++)
this.domains[i] = bitops.get_bits(this.data["DACR"], i*2+1, i*2);
};
ARMv7_CP15.prototype.dump_reg = function(name) {
var val = this.data[name];
display.log(name + ":\t" + toStringHex32(val) + " (" + toStringBin32(val) + ")");
};
ARMv7_CP15.prototype.sctlr_get_nmfi = function() {
var sctlr = this.data["SCTLR"];
return (sctlr >>> 27) & 1;
};
ARMv7_CP15.prototype.dump_sctlr = function() {
var sctlr = this.data["SCTLR"];
var val;
var msgs = new Array();
val = bitops.get_bit(sctlr, 29);
msgs.push("AFE=" + (val ? "simple" : "full"));
val = bitops.get_bit(sctlr, 28);
msgs.push("TRE=" + (val ? "enabled" : "disabled"));
val = bitops.get_bit(sctlr, 27);
msgs.push("NMFI=" + (val ? "non-maskable" : "maskable"));
val = bitops.get_bit(sctlr, 24);
msgs.push("VE=" + val);
val = bitops.get_bit(sctlr, 21);
msgs.push("FI=" + (val ? "all" : "some"));
val = bitops.get_bit(sctlr, 17);
msgs.push("HA=" + (val ? "enabled" : "disabled"));
val = bitops.get_bit(sctlr, 13);
msgs.push("V=" + val);
val = bitops.get_bit(sctlr, 1);
msgs.push("A=" + (val ? "check unaligned" : "NOT check unaligned"));
val = bitops.get_bit(sctlr, 0);
msgs.push("MMU=" + (val ? "enabled" : "disabled"));
display.log("SCTLR: " + msgs.join(", "));
};
ARMv7_CP15.prototype.dump = function() {
this.dump_reg("CSSELR");
this.dump_reg("TTBCR");
this.dump_reg("SCTLR");
this.dump_reg("TTBR0");
this.dump_reg("TTBR1");
this.dump_reg("DACR");
this.dump_sctlr();
display.log("domains=" + this.domains.toString());
display.log("interrupt vector address=" + this.interrupt_vector_address.toString(16));
};
ARMv7_CP15.prototype.dump_inst = function(inst) {
var opc1 = bitops.get_bits(inst, 23, 21);
var crn = bitops.get_bits(inst, 19, 16);
var opc2 = bitops.get_bits(inst, 7, 5);
var crm = bitops.get_bits(inst, 3, 0);
var msg = "";
msg += "crn=" + crn.toString(16) + "(" + crn.toString(2) + ")";
msg += ", ";
msg += "opc1=" + opc1.toString(16) + "(" + opc1.toString(2) + ")";
msg += ", ";
msg += "crm=" + crm.toString(16) + "(" + crm.toString(2) + ")";
msg += ", ";
msg += "opc2=" + opc2.toString(16) + "(" + opc2.toString(2) + ")";
logger.log(msg);
};
ARMv7_CP15.prototype.dump_value = function(value, name) {
this.output_value(display, value, name);
};
ARMv7_CP15.prototype.log_value = function(value, name) {
if (!this.options.enable_logger)
return;
this.output_value(logger, value, name);
};
ARMv7_CP15.prototype.output_value = function(target, value, name) {
if (name)
target.log(name + "=" + value.toString(10) + "\t" + toStringHex32(value) + "(" + toStringBin32(value) + ")");
else
target.log("value=" + value.toString(10) + "\t" + toStringHex32(value) + "(" + toStringBin32(value) + ")");
};
ARMv7_CP15.prototype.set_memory_abort = function(vaddr, status, is_write) {
this.data["DFAR"] = vaddr;
this.data["IFAR"] = vaddr; // XXX
var dfsr = is_write ? (1 << 11) : 0;
// This bit is for hardware error, so we can ignore it.
//dfsr = bitops.set_bit(dfsr, 10, is_write);
dfsr = dfsr + status;
this.data["DFSR"] = dfsr;
this.data["IFSR"] = dfsr; // XXX
};
================================================
FILE: js/armv7-cpu.js
================================================
/*!
* Javascript ARMv7 Emulator
*
* Copyright 2012, Ryota Ozaki
* Dual licensed under the MIT or GPL Version 2 licenses.
*/
function ARMv7_CPU(options, memctlr) {
this.options = options;
this.memctlr = memctlr;
this.USR_MODE = 0x10;
this.FIQ_MODE = 0x11;
this.IRQ_MODE = 0x12;
this.SVC_MODE = 0x13;
this.MON_MODE = 0x16;
this.ABT_MODE = 0x17;
this.UND_MODE = 0x1b;
this.SYS_MODE = 0x1f;
this.mode2string = new Array();
this.mode2string[this.USR_MODE] = "USR";
this.mode2string[this.FIQ_MODE] = "FIQ";
this.mode2string[this.IRQ_MODE] = "IRQ";
this.mode2string[this.SVC_MODE] = "SVC";
this.mode2string[this.MON_MODE] = "MON";
this.mode2string[this.ABT_MODE] = "ABT";
this.mode2string[this.UND_MODE] = "UND";
this.mode2string[this.SYS_MODE] = "SYS";
this.is_good_mode = new Object();
this.is_good_mode[this.USR_MODE] = true;
this.is_good_mode[this.FIQ_MODE] = true;
this.is_good_mode[this.IRQ_MODE] = true;
this.is_good_mode[this.SVC_MODE] = true;
this.is_good_mode[this.ABT_MODE] = true;
this.is_good_mode[this.UND_MODE] = true;
this.is_good_mode[this.SYS_MODE] = true;
this.regs = new Array();
for (i = 0; i < 16; i++)
this.regs[i] = 0;
/*
* regs[10]: SL:
* regs[11]: FP:
* regs[12]: IP: A general register
* regs[13]: SP: Stack pointer
* regs[14]: LR: Link register
* regs[15]: PC: Program counter
*/
this.regs_usr = new Array();
for (i = 0; i < 16; i++)
this.regs_usr[i] = 0;
this.regs_svc = new Array();
this.regs_svc[13] = 0;
this.regs_svc[14] = 0;
this.regs_mon = new Array();
this.regs_mon[13] = 0;
this.regs_mon[14] = 0;
this.regs_abt = new Array();
this.regs_abt[13] = 0;
this.regs_abt[14] = 0;
this.regs_und = new Array();
this.regs_und[13] = 0;
this.regs_und[14] = 0;
this.regs_irq = new Array();
this.regs_irq[13] = 0;
this.regs_irq[14] = 0;
this.regs_fiq = new Array();
this.regs_fiq[8] = 0;
this.regs_fiq[9] = 0;
this.regs_fiq[10] = 0;
this.regs_fiq[11] = 0;
this.regs_fiq[12] = 0;
this.regs_fiq[13] = 0;
this.regs_fiq[14] = 0;
// CPSR: Current program status register
/*
* bit[31]: N: Negative condition code flag (APSR)
* bit[30]: Z: Zero condition code flag (APSR)
* bit[29]: C: Carry condition code flag (APSR)
* bit[28]: V: Overflow condition code flag (APSR)
* bit[27]: Q: Cumulative saturation flag (APSR)
* bits[26:25]: IT: If-Then execution state bits
* bit[24]: J: Jazelle bit
* bits[23:20]: Reserved
* bits[19:16]: Greater than or Equal flags (APSR)
* bit[9]: E: Endianness execution state bit
* bit[8]: A: Asynchronous abort disable bit
* bit[7]: I: Interrupt disable bit
* bit[6]: F: Fast interrupt disable bit
* bit[5]: T: Thumb execution state bit
* bits[4:0]: M: Mode field
*/
this.cpsr = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
// SPSR: banked Saved Program Status Register
this.spsr_svc = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.spsr_mon = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.spsr_abt = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.spsr_und = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.spsr_irq = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.spsr_fiq = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
this.mmu = new ARMv7_MMU(this, this.memctlr);
this.coprocs = new Array();
for (i = 0; i < 16; i++)
this.coprocs[i] = null;
this.coprocs[15] = new ARMv7_CP15(options, this);
this.mmu.cp15 = this.coprocs[15];
this.shift_t = 0;
this.shift_n = 0;
this.carry_out = 0;
this.overflow = 0;
this.SRType_LSL = 0;
this.SRType_LSR = 1;
this.SRType_ASR = 2;
this.SRType_RRX = 3;
this.SRType_ROR = 4;
this.no_cond_insts = new Object();
this.no_cond_insts["cps"] = true;
this.no_cond_insts["clrex"] = true;
this.no_cond_insts["dsb"] = true;
this.no_cond_insts["dmb"] = true;
this.no_cond_insts["isb"] = true;
this.allow_unaligned = new Array();
this.allow_unaligned["ldrh"] = true;
this.allow_unaligned["ldrht"] = true;
this.allow_unaligned["ldrsh_imm"] = true;
this.allow_unaligned["ldrsh_reg"] = true;
this.allow_unaligned["ldrsht"] = true;
this.allow_unaligned["strh_imm"] = true;
this.allow_unaligned["strh_reg"] = true;
this.allow_unaligned["strht"] = true;
this.allow_unaligned["tbh"] = true;
this.allow_unaligned["ldr_imm"] = true;
this.allow_unaligned["ldr_reg"] = true;
this.allow_unaligned["ldr_lit"] = true;
this.allow_unaligned["ldrt"] = true;
this.allow_unaligned["str_imm"] = true;
this.allow_unaligned["str_reg"] = true;
this.allow_unaligned["strt"] = true;
this.is_halted = false;
this.current = "";
}
ARMv7_CPU.prototype.save = function() {
var params = Object();
params.regs = this.regs;
params.regs_usr = this.regs_usr;
params.regs_svc = this.regs_svc;
params.regs_mon = this.regs_mon;
params.regs_abt = this.regs_abt;
params.regs_und = this.regs_und;
params.regs_irq = this.regs_irq;
params.regs_fiq = this.regs_fiq;
params.spsr_svc = this.spsr_svc;
params.spsr_mon = this.spsr_mon;
params.spsr_abt = this.spsr_abt;
params.spsr_und = this.spsr_und;
params.spsr_irq = this.spsr_irq;
params.spsr_fiq = this.spsr_fiq;
params.cpsr = this.cpsr;
params.spsr = this.spsr;
params.is_halted = this.is_halted;
return params;
};
ARMv7_CPU.prototype.restore = function(params) {
this.regs = params.regs;
this.regs_usr = params.regs_usr;
this.regs_svc = params.regs_svc;
this.regs_mon = params.regs_mon;
this.regs_abt = params.regs_abt;
this.regs_und = params.regs_und;
this.regs_irq = params.regs_irq;
this.regs_fiq = params.regs_fiq;
this.spsr_svc = params.spsr_svc;
this.spsr_mon = params.spsr_mon;
this.spsr_abt = params.spsr_abt;
this.spsr_und = params.spsr_und;
this.spsr_irq = params.spsr_irq;
this.spsr_fiq = params.spsr_fiq;
this.cpsr = params.cpsr;
this.spsr = params.spsr;
this.is_halted = params.is_halted;
};
ARMv7_CPU.prototype.dump = function(params) {
display.log("mode=" + this.mode2string[this.cpsr.m]);
display.log("halted=" + this.is_halted);
this.dump_regs(null);
this.dump_banked_regs();
this.dump_cpsr();
this.dump_spsr();
};
ARMv7_CPU.prototype.dump_stack = function() {
var sp = this.regs[13];
display.wipe();
display.log("Stack values:");
for (var i = 0; i < 50; i++) {
var addr = sp + i*4;
var val = this.ld_word(addr);
display.log("\t" + toStringHex32(addr) + ":\t" + toStringHex32(val) + "(" + val.toString(10) + ")");
}
};
ARMv7_CPU.prototype.get_pc = function() {
return this.regs[15] + 8;
};
ARMv7_CPU.prototype.reg = function(i) {
if (i == 15)
return this.get_pc();
else
return this.regs[i];
};
ARMv7_CPU.prototype.dump_banked_regs = function() {
this.output_banked_regs(display);
};
ARMv7_CPU.prototype.output_banked_regs = function(target) {
var indent = " ";
var msg = "USR: ";
var i;
for (i = 0; i <= 7; i++)
msg += "[ " + i.toString() + "]=" + toStringHex32(this.regs_usr[i]) + " ";
target.log(msg);
msg = " ";
for (i = 8; i <= 9; i++)
msg += "[ " + i.toString() + "]=" + toStringHex32(this.regs_usr[i]) + " ";
for (i = 10; i <= 15; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_usr[i]) + " ";
target.log(msg);
msg = "SVC: " + indent;
for (i = 13; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_svc[i]) + " ";
target.log(msg);
msg = "MON: " + indent;
for (i = 13; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_mon[i]) + " ";
target.log(msg);
msg = "ABT: " + indent;
for (i = 13; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_abt[i]) + " ";
target.log(msg);
msg = "UND: " + indent;
for (i = 13; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_und[i]) + " ";
target.log(msg);
msg = "IRQ: " + indent;
for (i = 13; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_irq[i]) + " ";
target.log(msg);
msg = "FIQ: ";
for (i = 8; i <= 9; i++)
msg += "[ " + i.toString() + "]=" + toStringHex32(this.regs_fiq[i]) + " ";
for (i = 10; i <= 14; i++)
msg += "[" + i.toString() + "]=" + toStringHex32(this.regs_fiq[i]) + " ";
target.log(msg);
};
ARMv7_CPU.prototype.log_cpsr = function() {
if (!this.options.enable_logger)
return;
this.output_cpsr(logger);
};
ARMv7_CPU.prototype.dump_cpsr = function() {
this.output_cpsr(display);
};
ARMv7_CPU.prototype.dump_spsr = function() {
this.output_spsr(display);
};
ARMv7_CPU.prototype.log_apsr = function() {
if (!this.options.enable_logger)
return;
this.output_apsr(logger);
};
ARMv7_CPU.prototype.dump_apsr = function() {
this.output_apsr(display);
};
ARMv7_CPU.prototype.output_apsr = function(target) {
var msg = "APSR: ";
msg += "N[" + this.cpsr.n + "] ";
msg += "Z[" + this.cpsr.z + "] ";
msg += "C[" + this.cpsr.c + "] ";
msg += "V[" + this.cpsr.v + "] ";
msg += "Q[" + this.cpsr.q + "] ";
target.log(msg);
};
ARMv7_CPU.prototype.output_psr = function(name, psr, target) {
var msg = name + ": ";
msg += "N[" + psr.n + "] ";
msg += "Z[" + psr.z + "] ";
msg += "C[" + psr.c + "] ";
msg += "V[" + psr.v + "] ";
msg += "Q[" + psr.q + "] ";
msg += "A[" + psr.a + "] ";
msg += "I[" + psr.i + "] ";
msg += "F[" + psr.f + "] ";
msg += "M[" + psr.m.toString(2) + "] ";
target.log(msg);
};
ARMv7_CPU.prototype.output_cpsr = function(target) {
this.output_psr("CPSR", this.cpsr, target);
};
ARMv7_CPU.prototype.output_spsr = function(target) {
this.output_psr("SPSR_svc", this.spsr_svc, target);
this.output_psr("SPSR_mon", this.spsr_mon, target);
this.output_psr("SPSR_abt", this.spsr_abt, target);
this.output_psr("SPSR_und", this.spsr_und, target);
this.output_psr("SPSR_irq", this.spsr_irq, target);
this.output_psr("SPSR_fiq", this.spsr_fiq, target);
};
ARMv7_CPU.prototype.log_regs = function(oldregs) {
if (!this.options.enable_logger)
return;
this.output_regs(logger, oldregs);
};
ARMv7_CPU.prototype.dump_regs = function(oldregs) {
this.output_regs(display, oldregs);
};
ARMv7_CPU.prototype.output_regs = function(target, oldregs) {
var i;
var indent = " ";
var msg = indent;
if (oldregs === null) {
for (i = 0; i < 8; i++)
msg += "[ " + i.toString() + "]=" + toStringHex32(this.regs[i]) + " ";
target.log(msg);
msg = indent;
for (i = 8; i < 16; i++)
msg += "[" + (i < 10 ? " " : "") + i.toString() + "]=" + toStringHex32(this.regs[i]) + " ";
target.log(msg);
} else {
var changed = false;
for (i = 0; i < 8; i++) {
if (this.regs[i] == oldregs[i])
// " [10]=60000093"
msg += " ";
else {
msg += "[ " + i.toString() + "]=" + toStringHex32(this.regs[i]) + " ";
changed = true;
}
}
if (changed)
target.log(msg);
changed = false;
msg = indent;
for (i = 8; i < 15; i++) { // PC will change every execution, so don't show it
if (this.regs[i] == oldregs[i]) {
// " [10]=60000093"
msg += " ";
} else {
msg += "[" + (i < 10 ? " " : "") + i.toString() + "]=" + toStringHex32(this.regs[i]) + " ";
changed = true;
}
}
if (changed)
target.log(msg);
}
};
ARMv7_CPU.prototype.dump_value = function(value, name) {
this.output_value(display, value, name);
};
ARMv7_CPU.prototype.log_value = function(value, name) {
if (!this.options.enable_logger)
return;
this.output_value(logger, value, name);
};
ARMv7_CPU.prototype.output_value = function(target, value, name) {
if (name)
target.log(name + "=" + value.toString(10) + "\t" + toStringHex32(value) + "(" + toStringBin32(value) + ")");
else
target.log("value=" + value.toString(10) + "\t" + toStringHex32(value) + "(" + toStringBin32(value) + ")");
};
ARMv7_CPU.prototype.is_bad_mode = function(mode) {
switch (mode) {
case this.SVC_MODE:
case this.IRQ_MODE:
case this.USR_MODE:
case this.ABT_MODE:
case this.FIQ_MODE:
case this.UND_MODE:
case this.SYS_MODE:
return false;
case this.MON_MODE: // !HaveSecurityExt()
default:
return true;
}
};
ARMv7_CPU.prototype.is_priviledged = function() {
var mode = this.cpsr.m;
if (mode == this.USR_MODE)
return false;
else
return true;
};
ARMv7_CPU.prototype.is_user_or_system = function() {
var mode = this.cpsr.m;
if (mode == this.USR_MODE || mode == this.SYS_MODE)
return true;
else
return false;
};
ARMv7_CPU.prototype.is_secure = function() {
return false;
};
ARMv7_CPU.prototype.scr_get_aw = function() {
return 1; // the CPSR.A bit can be modified in any security state.
};
ARMv7_CPU.prototype.scr_get_fw = function() {
return 1; // the CPSR.F bit can be modified in any security state.
};
ARMv7_CPU.prototype.nsacr_get_rfr = function() {
return 0; // FIQ mode and the FIQ Banked registers are accessible in Secure and Non-secure security states.
};
ARMv7_CPU.prototype.sctlr_get_nmfi = function() {
return this.coprocs[15].sctlr_get_nmfi();
};
ARMv7_CPU.prototype.parse_psr = function(value) {
var psr = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
psr.n = value >>> 31;
psr.z = (value >>> 30) & 1;
psr.c = (value >>> 29) & 1;
psr.v = (value >>> 28) & 1;
psr.q = (value >>> 27) & 1;
psr.e = (value >>> 9) & 1;
psr.a = (value >>> 8) & 1;
psr.i = (value >>> 7) & 1;
psr.f = (value >>> 6) & 1;
psr.t = (value >>> 5) & 1;
psr.m = value & 0x1f;
return psr;
};
ARMv7_CPU.prototype.psr_to_value = function(psr) {
var value = psr.m;
value += psr.t << 5;
value += psr.f << 6;
value += psr.i << 7;
value += psr.a << 8;
value += psr.e << 9;
value += psr.q << 27;
value += psr.v << 28;
value += psr.c << 29;
value += psr.z << 30;
value += psr.n << 31;
return value;
};
ARMv7_CPU.prototype.clone_psr = function(src) {
var dst = {n:0, z:0, c:0, v:0, q:0, e:0, a:0, i:0, f:0, t:0, m:0};
dst.n = src.n;
dst.z = src.z;
dst.c = src.c;
dst.v = src.v;
dst.q = src.q;
dst.e = src.e;
dst.a = src.a;
dst.i = src.i;
dst.f = src.f;
dst.t = src.t;
dst.m = src.m;
return dst;
};
ARMv7_CPU.prototype.set_current_spsr = function(spsr) {
switch (this.cpsr.m) {
case this.USR_MODE:
throw "set_current_spsr user";
break;
case this.FIQ_MODE:
this.spsr_fiq = spsr;
break;
case this.IRQ_MODE:
this.spsr_irq = spsr;
break;
case this.SVC_MODE:
this.spsr_svc = spsr;
break;
case this.MON_MODE:
this.spsr_mon = spsr;
break;
case this.ABT_MODE:
this.spsr_abt = spsr;
break;
case this.UND_MODE:
this.spsr_und = spsr;
break;
case this.SYS_MODE:
throw "set_current_spsr system user";
break;
default:
throw "set_current_spsr unknown";
break;
}
};
ARMv7_CPU.prototype.get_current_spsr = function() {
switch (this.cpsr.m) {
case this.USR_MODE:
throw "get_current_spsr user";
break;
case this.FIQ_MODE:
return this.spsr_fiq;
case this.IRQ_MODE:
return this.spsr_irq;
case this.SVC_MODE:
return this.spsr_svc;
case this.MON_MODE:
return this.spsr_mon;
case this.ABT_MODE:
return this.spsr_abt;
case this.UND_MODE:
return this.spsr_und;
case this.SYS_MODE:
throw "get_current_spsr system user";
break;
default:
throw "get_current_spsr unknown";
break;
}
return null;
};
ARMv7_CPU.prototype.spsr_write_by_instr0 = function(spsr, psr, bytemask) {
if (this.is_user_or_system())
this.abort_unpredictable("spsr_write_by_instr0");
if (bytemask & 8) {
spsr.n = psr.n;
spsr.z = psr.z;
spsr.c = psr.c;
spsr.v = psr.v;
spsr.q = psr.q;
}
if (bytemask & 4) {
spsr.ge = psr.ge;
}
if (bytemask & 2) {
spsr.e = psr.e;
spsr.a = psr.a;
}
if (bytemask & 1) {
spsr.i = psr.i;
spsr.f = psr.f;
spsr.t = psr.t;
if (!this.is_good_mode[psr.m])
this.abort_unpredictable("spsr_write_by_instr0", psr.m);
else
spsr.m = psr.m;
}
return spsr;
};
ARMv7_CPU.prototype.spsr_write_by_instr = function(psr, bytemask) {
var spsr = this.get_current_spsr();
this.spsr_write_by_instr0(spsr, psr, bytemask);
this.set_current_spsr(spsr); // XXX
};
ARMv7_CPU.prototype.cpsr_write_by_instr = function(psr, bytemask, affect_execstate) {
var is_priviledged = this.is_priviledged();
var nmfi = this.sctlr_get_nmfi() == 1;
if (this.options.enable_logger) {
var oldregs = new Array();
this.store_regs(oldregs);
this.log_cpsr();
}
if (bytemask & 8) {
this.cpsr.n = psr.n;
this.cpsr.z = psr.z;
this.cpsr.c = psr.c;
this.cpsr.v = psr.v;
this.cpsr.q = psr.q;
}
if (bytemask & 2) {
this.cpsr.e = psr.e;
if (is_priviledged && (this.is_secure() || this.scr_get_aw() == 1))
this.cpsr.a = psr.a;
}
if (bytemask & 1) {
if (is_priviledged) {
this.cpsr.i = psr.i;
}
if (is_priviledged && (this.is_secure() || this.scr_get_fw() == 1) && (!nmfi || psr.f === 0))
this.cpsr.f = psr.f;
if (affect_execstate)
this.cpsr.t = psr.t;
if (is_priviledged) {
if (!this.is_good_mode[psr.m])
this.abort_unpredictable("cpsr_write_by_instr", psr.m);
else {
if (!this.is_secure() && psr.m == this.MON_MODE)
this.abort_unpredictable("cpsr_write_by_instr", psr.m);
if (!this.is_secure() && psr.m == this.FIQ_MODE && this.nsacr_get_rfr() == 1)
this.abort_unpredictable("cpsr_write_by_instr", psr.m);
if (this.cpsr.m != psr.m)
this.change_mode(psr.m);
}
}
}
if (this.options.enable_logger) {
this.log_cpsr();
this.log_regs(oldregs);
}
};
ARMv7_CPU.prototype.save_to_regs = function(mode) {
switch (mode) {
case this.USR_MODE:
this.regs_usr[13] = this.regs[13];
this.regs_usr[14] = this.regs[14];
break;
case this.FIQ_MODE:
this.regs_fiq[8] = this.regs[8];
this.regs_fiq[9] = this.regs[9];
this.regs_fiq[10] = this.regs[10];
this.regs_fiq[11] = this.regs[11];
this.regs_fiq[12] = this.regs[12];
this.regs_fiq[13] = this.regs[13];
this.regs_fiq[14] = this.regs[14];
break;
case this.IRQ_MODE:
this.regs_irq[13] = this.regs[13];
this.regs_irq[14] = this.regs[14];
break;
case this.SVC_MODE:
this.regs_svc[13] = this.regs[13];
this.regs_svc[14] = this.regs[14];
break;
case this.MON_MODE:
this.regs_mon[13] = this.regs[13];
this.regs_mon[14] = this.regs[14];
break;
case this.ABT_MODE:
this.regs_abt[13] = this.regs[13];
this.regs_abt[14] = this.regs[14];
break;
case this.UND_MODE:
this.regs_und[13] = this.regs[13];
this.regs_und[14] = this.regs[14];
break;
case this.SYS_MODE:
throw "save_to_regs system";
break;
default:
throw "save_to_regs unknown: " + mode.toString(16);
break;
}
};
ARMv7_CPU.prototype.restore_from_regs = function(mode) {
switch (mode) {
case this.USR_MODE:
this.regs[13] = this.regs_usr[13];
this.regs[14] = this.regs_usr[14];
break;
case this.FIQ_MODE:
this.regs[8] = this.regs_fiq[8];
this.regs[9] = this.regs_fiq[9];
this.regs[10] = this.regs_fiq[10];
this.regs[11] = this.regs_fiq[11];
this.regs[12] = this.regs_fiq[12];
this.regs[13] = this.regs_fiq[13];
this.regs[14] = this.regs_fiq[14];
break;
case this.IRQ_MODE:
this.regs[13] = this.regs_irq[13];
this.regs[14] = this.regs_irq[14];
break;
case this.SVC_MODE:
this.regs[13] = this.regs_svc[13];
this.regs[14] = this.regs_svc[14];
break;
case this.MON_MODE:
this.regs[13] = this.regs_mon[13];
this.regs[14] = this.regs_mon[14];
break;
case this.ABT_MODE:
this.regs[13] = this.regs_abt[13];
this.regs[14] = this.regs_abt[14];
break;
case this.UND_MODE:
this.regs[13] = this.regs_und[13];
this.regs[14] = this.regs_und[14];
break;
case this.SYS_MODE:
throw "restore_from_regs system";
break;
default:
throw "restore_from_regs unknown: " + mode.toString(16);
break;
}
};
ARMv7_CPU.prototype.change_mode = function(mode) {
if (!mode)
throw "Invalid mode: " + mode;
if (this.options.enable_logger)
logger.log("changing mode from " + this.mode2string[this.cpsr.m] + " to " + this.mode2string[mode]);
this.save_to_regs(this.cpsr.m);
this.cpsr.m = mode;
this.restore_from_regs(this.cpsr.m);
};
ARMv7_CPU.prototype.set_apsr = function(val, set_overflow) {
this.cpsr.n = val >>> 31;
this.cpsr.z = (val === 0) ? 1 : 0;
this.cpsr.c = this.carry_out;
if (set_overflow)
this.cpsr.v = this.overflow;
if (this.options.enable_logger)
this.log_apsr();
};
ARMv7_CPU.prototype.store_regs = function(regs) {
for (var i = 0; i < 16; i++)
regs[i] = this.regs[i];
};
/*
* Coprocessors
*/
ARMv7_CPU.prototype.coproc_accepted = function(cp) {
return cp == 15; // FIXME
};
ARMv7_CPU.prototype.coproc_get_word = function(cp, inst) {
return this.coprocs[cp].get_word(inst);
};
ARMv7_CPU.prototype.coproc_send_word = function(cp, inst, word) {
return this.coprocs[cp].send_word(inst, word);
};
ARMv7_CPU.prototype.coproc_internal_operation = function(cp, inst) {
this.log_value(cp, "cp");
throw "coproc";
return this.coprocs[cp].internal_operation(inst);
};
/*
* Alignment
*/
ARMv7_CPU.prototype.align = function(value, align) {
assert((value & 3) === 0, "align");
return value; // FIXME
};
ARMv7_CPU.prototype.unaligned_support = function() {
return true;
};
/*
* Instruction printers
*/
ARMv7_CPU.prototype.abort_unknown_inst = function(inst, addr) {
display.log("\nUnknown instruction: " + toStringInst(inst));
throw "UNKNOWN";
};
ARMv7_CPU.prototype.abort_simdvfp_inst = function(inst, addr) {
display.log("\nSIMD or VFP instruction: " + toStringInst(inst));
throw "SIMD or VFP";
};
ARMv7_CPU.prototype.abort_not_impl = function(name, inst, addr) {
display.log("\n--" + name + " not implemented: " + toStringInst(inst));
throw "NOT IMPLEMENTED: " + name;
};
ARMv7_CPU.prototype.abort_undefined_instruction = function(category, inst, addr) {
display.log("\nUndefined instruction in " + category + ": " + toStringInst(inst));
throw "UNDEFINED: " + category;
};
ARMv7_CPU.prototype.abort_unpredictable = function(category, value) {
display.log("\nUnpredictable in " + category + ": " + value.toString(16) + "(" + value.toString(2) + ")");
throw "UNPREDICTABLE: " + category;
};
ARMv7_CPU.prototype.abort_unpredictable_instruction = function(category, inst, addr) {
display.log("\nUnpredictable instruction in " + category + ": " + inst.toString(16) + "(" + inst.toString(2) + ")");
throw "UNPREDICTABLE: " + category;
};
ARMv7_CPU.prototype.abort_decode_error = function(inst, addr) {
display.log("\nDecode error: " + toStringInst(inst));
throw "Decode error";
};
ARMv7_CPU.prototype.print_inst = function(name, inst, addr) {
if (!this.options.enable_logger)
return;
var msg = "\n@" + toStringHex32(addr) + ": ";
if (name) {
msg += toStringInst(inst) + ": " + name;
} else {
msg += toStringInst(inst);
}
logger.log(msg);
};
ARMv7_CPU.prototype.toRegName = function(i) {
switch (i) {
case 15: return "pc";
case 14: return "lr";
case 13: return "sp";
case 12: return "ip";
case 11: return "fp";
case 10: return "sl";
default: return "r" + i.toString();
}
};
ARMv7_CPU.prototype.print_inst_unimpl = function(addr, inst, name) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_uxtab = function(addr, inst, name, d, n, m, rotation) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
var items = [];
items.push(this.toRegName(d));
if (n)
items.push(this.toRegName(n));
items.push(this.toRegName(m));
if (rotation)
items.push(rotation.toString());
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_ubfx = function(addr, inst, name, d, n, msbit, lsbit) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
var items = [];
items.push(this.toRegName(d));
if (n)
items.push(this.toRegName(n));
items.push("#" + msbit.toString());
items.push("#" + lsbit.toString());
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_mcrmrc = function(addr, inst, name, t, cp) {
if (!this.options.enable_tracer)
return;
var opc1 = bitops.get_bits(inst, 23, 21);
var crn = bitops.get_bits(inst, 19, 16);
var opc2 = bitops.get_bits(inst, 7, 5);
var crm = bitops.get_bits(inst, 3, 0);
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
var items = [];
items.push(cp.toString());
items.push(opc1.toString());
items.push(this.toRegName(t));
items.push("cr" + crn.toString());
items.push("cr" + crm.toString());
//if (opc2)
items.push("{" + opc2.toString() + "}");
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_svc = function(addr, inst, val) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
msg += "svc\t";
msg += "0x" + toStringHex32(val);
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_mrs = function(addr, inst, d) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
msg += "mrs\t";
msg += this.toRegName(d) + ", CPSR";
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_msr = function(addr, inst, n, imm) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
msg += "msr\t";
if (n) {
msg += "CPSR_c, " + this.toRegName(n);
} else if (imm) {
var imm_str = "#" + imm.toString();
msg += "CPSR_c, " + imm_str;
}
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_ldstm = function(addr, inst, name, wback, t, reglist) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
var items = [];
if (t !== null)
items.push(this.toRegName(t) + (wback ? "!" : ""));
var _items = [];
for (var i in reglist) {
_items.push(this.toRegName(reglist[i]));
}
items.push("{" + _items.join(", ") + "}");
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_rsr = function(addr, inst, name, s, d, n, m, stype, sn) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + (s == 1 ? "s" : "") + "\t";
var items = [];
if (d)
items.push(this.toRegName(d));
if (n)
items.push(this.toRegName(n));
if (m)
items.push(this.toRegName(m));
items.push(this.shift_type_name(stype) + " " + this.toRegName(sn));
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_mul = function(addr, inst, name, s, dhi, dlo, n, m) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + (s == 1 ? "s" : "") + "\t";
var items = [];
if (dlo !== null)
items.push(this.toRegName(dlo));
if (dhi !== null)
items.push(this.toRegName(dhi));
if (n !== null)
items.push(this.toRegName(n));
if (m !== null)
items.push(this.toRegName(m));
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_reg = function(addr, inst, name, s, d, n, m, stype, sn, ldst, wback) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + (s == 1 ? "s" : "") + "\t";
var items = [];
if (d !== null)
items.push(this.toRegName(d));
if (ldst) {
var _items = [];
if (n !== null)
_items.push(this.toRegName(n));
if (m !== null)
_items.push(this.toRegName(m));
if (sn)
_items.push(this.shift_type_name(stype) + " #" + sn.toString());
items.push("[" + _items.join(", ") + "]" + (wback ? "!" : ""));
} else {
if (n !== null)
items.push(this.toRegName(n));
if (m !== null)
items.push(this.toRegName(m));
if (sn)
items.push(this.shift_type_name(stype) + " #" + sn.toString());
}
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_imm = function(addr, inst, name, s, d, n, imm, ldst, wback, add, index) {
if (!this.options.enable_tracer)
return;
var is_add = add == undefined ? true : add;
var is_index = index == undefined ? true : index;
var imm_str = "#" + (is_add ? imm : -imm).toString();
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + (s == 1 ? "s" : "") + "\t";
var items = [];
if (d !== null)
items.push(this.toRegName(d));
if (ldst) {
if (is_index) {
var _items = [];
_items.push(this.toRegName(n));
if (imm !== 0)
_items.push(imm_str);
items.push("[" + _items.join(", ") + "]" + (wback ? "!" : ""));
} else {
items.push("[" + this.toRegName(n) + "]");
items.push(imm_str);
}
} else {
if (n !== null)
items.push(this.toRegName(n));
items.push(imm_str);
}
msg += items.join(', ');
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.print_inst_branch = function(addr, inst, name, branch_to, reg) {
if (!this.options.enable_tracer)
return;
var msg = toStringHex32(addr) + ":\t";
msg += toStringHex32(inst) + "\t";
var pf = this.cond_postfix(inst);
msg += name + pf + "\t";
if (reg) {
msg += this.toRegName(reg);
msg += "\t; " + toStringHex32(branch_to);
} else {
if (Symbols[branch_to])
msg += toStringHex32(branch_to) + " <" + Symbols[branch_to] + ">";
else
msg += toStringHex32(branch_to);
}
tracer.log(msg, inst);
};
ARMv7_CPU.prototype.sp_used = function(name, inst) {
if (!this.options.enable_logger)
return;
logger.log("SP: " + name + ": " + toStringInst(inst));
};
ARMv7_CPU.prototype.push_used = function(name, list) {
if (!this.options.enable_logger)
return;
logger.log("PUSH: " + name + ": " + toStringBin16(list));
};
ARMv7_CPU.prototype.pop_used = function(name, list) {
if (!this.options.enable_logger)
return;
logger.log("POP: " + name + ": " + toStringBin16(list));
};
ARMv7_CPU.prototype.print_pc = function(newpc, oldpc) {
if (!this.options.enable_logger)
return;
if (oldpc)
logger.log("PC: " + newpc.toString(16) + " from " + oldpc.toString(16) + "(" + (newpc-oldpc).toString(16) + ")");
else
logger.log("PC: " + newpc.toString(16));
};
ARMv7_CPU.prototype.call_supervisor = function() {
throw "SUPERVISOR";
};
ARMv7_CPU.prototype.toStringSymbol = function(addr) {
if (Symbols[addr])
return Symbols[addr] + "(" + addr.toString(16) + ")";
else
return addr.toString(16);
};
/*
* Load/Store operations
*/
ARMv7_CPU.prototype.allow_unaligned_access = function() {
if (!this.mmu.check_unaligned)
return true;
else
return false;
};
ARMv7_CPU.prototype.ld_word = function(addr) {
if (addr == this.options.show_act_on_viraddr)
display.log("@" + this.regs[15].toString(16) + ": " + this.toStringSymbol(addr) + ": read");
var phyaddr;
if (addr & 3) {
if (!this.allow_unaligned_access()) {
throw "Unaligned ld_word: " + this.current + "@" + toStringHex32(addr);
} else {
var val = 0;
var mmu = this.mmu;
var memctlr = this.memctlr;
for (var i=0; i < 4; i++) {
phyaddr = mmu.trans_to_phyaddr(addr + i);
val = bitops.set_bits(val, 8*i+7, 8*i, memctlr.ld_byte(phyaddr));
}
return val;
}
} else {
phyaddr = this.mmu.trans_to_phyaddr(addr);
return this.memctlr.ld_word(phyaddr);
}
};
ARMv7_CPU.prototype.st_word = function(addr, word) {
if (addr == this.options.show_act_on_viraddr)
display.log("@" + this.regs[15].toString(16) + ": " + this.toStringSymbol(addr) + ": write " + toStringNum(word));
var phyaddr;
if (addr & 3) {
if (!this.allow_unaligned_access()) {
throw "Unaligned st_word: " + this.current + "@" + toStringHex32(addr);
} else {
var mmu = this.mmu;
var memctlr = this.memctlr;
for (var i=0; i < 4; i++) {
phyaddr = mmu.trans_to_phyaddr(addr + i);
memctlr.st_byte(phyaddr, bitops.get_bits(word, 8*i+7, 8*i));
}
}
} else {
phyaddr = this.mmu.trans_to_phyaddr(addr, true);
this.memctlr.st_word(phyaddr, word);
}
};
ARMv7_CPU.prototype.ld_halfword = function(addr) {
var phyaddr;
if (addr & 1) {
if (!this.allow_unaligned_access()) {
throw "Unaligned ld_halfword: " + this.current + "@" + toStringHex32(addr);
} else {
var val = 0;
var mmu = this.mmu;
var memctlr = this.memctlr;
for (var i=0; i < 2; i++) {
phyaddr = mmu.trans_to_phyaddr(addr + i);
val = bitops.set_bits(val, 8*i+7, 8*i, memctlr.ld_byte(phyaddr));
}
return val;
}
} else {
phyaddr = this.mmu.trans_to_phyaddr(addr);
return this.memctlr.ld_halfword(phyaddr);
}
};
ARMv7_CPU.prototype.st_halfword = function(addr, hw) {
var phyaddr;
if (addr & 1) {
if (!this.allow_unaligned_access()) {
throw "Unaligned st_halfword: " + this.current + "@" + toStringHex32(addr);
} else {
var mmu = this.mmu;
var memctlr = this.memctlr;
for (var i=0; i < 2; i++) {
phyaddr = mmu.trans_to_phyaddr(addr + i);
memctlr.st_byte(phyaddr, bitops.get_bits(hw, 8*i+7, 8*i));
}
}
} else {
phyaddr = this.mmu.trans_to_phyaddr(addr, true);
this.memctlr.st_halfword(phyaddr, hw);
}
};
ARMv7_CPU.prototype.ld_byte = function(addr) {
var phyaddr = this.mmu.trans_to_phyaddr(addr);
return this.memctlr.ld_byte(phyaddr);
};
ARMv7_CPU.prototype.st_byte = function(addr, b) {
var phyaddr = this.mmu.trans_to_phyaddr(addr, true);
this.memctlr.st_byte(phyaddr, b);
};
ARMv7_CPU.prototype.fetch_instruction = function(addr) {
var phyaddr = this.mmu.trans_to_phyaddr(addr);
return this.memctlr.ld_word_fast(phyaddr);
};
/*
* Shift Operations
*/
ARMv7_CPU.prototype.shift_type_name = function(type) {
switch (type) {
case this.SRType_LSL: return "lsl";
case this.SRType_LSR: return "lsr";
case this.SRType_ASR: return "asr";
case this.SRType_RRX: return "rrx";
case this.SRType_ROR: return "ror";
default: return "unknown";
}
};
ARMv7_CPU.prototype.shift = function(value, type, amount, carry_in) {
return this.shift_c(value, type, amount, carry_in);
};
ARMv7_CPU.prototype.decode_imm_shift = function(type, imm5) {
/*
* 0: LSL
* 1: LSR
* 2: ASR
* 3: RRX or ROR (ARM encoding)
* 3: RRX (In this emulator)
* 4: ROR (In this emulator)
*/
switch (type) {
case 0:
this.shift_t = type;
this.shift_n = imm5;
break;
case 1:
case 2:
this.shift_t = type;
if (imm5 === 0)
this.shift_n = 32;
else
this.shift_n = imm5;
break;
case 3:
if (imm5 === 0) {
this.shift_t = type;
this.shift_n = 1;
} else {
this.shift_t = this.SRType_ROR;
this.shift_n = imm5;
}
break;
default:
throw "decode_imm_shift";
break;
}
};
ARMv7_CPU.prototype.shift_c = function(value, type, amount, carry_in) {
var res;
var result;
if (amount === 0) {
this.carry_out = carry_in;
return value;
} else {
switch (type) {
// FIXME
case 0: // LSL
//assert(amount > 0, "lsl: amount > 0");
var val64 = new Number64(0, value);
var extended = val64.lsl(amount);
this.carry_out = extended.high & 1;
return extended.low;
case 1: // LSR
//assert(amount > 0, "lsr: amount > 0");
this.carry_out = (amount == 32) ? 0 : ((value >>> (amount - 1)) & 1);
result = bitops.lsr(value, amount);
//assert(result >= 0, "lsr: result = " + result.toString());
return result;
case 2: // ASR
//assert(amount > 0, "asr: amount > 0");
this.carry_out = (amount == 32) ? 0 : ((value >>> (amount - 1)) & 1);
result = bitops.asr(value, amount);
return result;
case 3: // RRX
this.carry_out = value & 1;
result = bitops.set_bit(value >>> 1, 31, carry_in);
//assert(result >= 0, "rrx");
return result;
case 4: // ROR
return this.ror_c(value, amount, true);
default:
throw "shift_c";
return 0;
}
}
};
ARMv7_CPU.prototype.ror_c = function(value, amount, write) {
//assert(amount !== 0);
var result = bitops.ror(value, amount);
//assert(result >= 0, "ror");
if (write)
this.carry_out = result >>> 31;
return result;
};
ARMv7_CPU.prototype.ror = function(val, rotation) {
if (rotation === 0)
return val;
return this.ror_c(val, rotation, false);
};
ARMv7_CPU.prototype.is_zero_bit = function(val) {
if (val === 0)
return 1;
else
return 0;
};
ARMv7_CPU.prototype.expand_imm_c = function(imm12, carry_in) {
var unrotated_value = imm12 & 0xff;
var amount = 2*(imm12 >>> 8);
if (!amount) {
this.carry_out = carry_in;
return unrotated_value;
}
return this.ror_c(unrotated_value, amount, true);
};
ARMv7_CPU.prototype.expand_imm = function(imm12) {
return this.expand_imm_c(imm12, this.cpsr.c);
};
ARMv7_CPU.prototype.add_with_carry = function(x, y, carry_in) {
var unsigned_sum = x + y + carry_in;
var signed_sum = (x|0) + (y|0) + carry_in;
//var result = bitops.get_bits64(unsigned_sum, 31, 0);
var result = unsigned_sum % 0x100000000;
if (result < 0)
result += 0x100000000;
this.carry_out = (result == unsigned_sum) ? 0 : 1;
this.overflow = ((result|0) == signed_sum) ? 0 : 1;
return result;
};
ARMv7_CPU.prototype.decode_reg_shift = function(type) {
this.shift_t = type;
return type;
};
ARMv7_CPU.prototype.cond_postfix = function(inst) {
var cond = bitops.get_bits(inst, 31, 28);
switch (cond) {
case 0: return "eq";
case 1: return "ne";
case 2: return "cs";
case 3: return "cc";
case 4: return "mi";
case 8: return "hi";
case 9: return "ls";
case 0xa: return "ge";
case 0xb: return "lt";
case 0xc: return "gt";
case 0xd: return "le";
default:
return "";
}
};
ARMv7_CPU.prototype.is_valid = function(inst) {
return (inst != 0xe1a00000 && inst !== 0); // NOP or NULL?
};
ARMv7_CPU.prototype.cond = function(inst) {
var cond = inst >>> 28;
var ret = false;
switch (cond >> 1) {
case 0:
ret = this.cpsr.z == 1; // EQ or NE
break;
case 1:
ret = this.cpsr.c == 1; // CS or CC
break;
case 2:
ret = this.cpsr.n == 1; // MI or PL
break;
case 3:
ret = this.cpsr.v == 1; // VS or VC
break;
case 4:
ret = this.cpsr.c == 1 && this.cpsr.z === 0; // HI or LS
break;
case 5:
ret = this.cpsr.n == this.cpsr.v; // GE or LT
break;
case 6:
ret = this.cpsr.n == this.cpsr.v && this.cpsr.z === 0; // GT or LE
break;
case 7:
ret = true; // AL
break;
default:
break;
}
if ((cond & 1) && cond !== 0xf)
ret = !ret;
return ret;
};
/*
*
* Instruction Execution
*
*/
/*
* Immediate
*/
ARMv7_CPU.prototype.adc_imm = function(inst, addr) {
this.print_inst("ADC (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var ret = this.add_with_carry(this.reg(n), imm32, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "adc", s, d, n, imm32);
};
ARMv7_CPU.prototype.add_imm = function(inst, addr) {
this.print_inst("ADD (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var ret = this.add_with_carry(this.reg(n), imm32, 0);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "add", s, d, n, imm32);
};
ARMv7_CPU.prototype.adr_a1 = function(inst, addr) {
this.print_inst("ADR A1", inst, addr);
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var ret = this.align(this.get_pc(), 4) + imm32;
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
}
this.print_inst_imm(addr, inst, "adr", null, d, null, imm32);
};
ARMv7_CPU.prototype.adr_a2 = function(inst, addr) {
this.print_inst("ADR A2", inst, addr);
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var ret = this.align(this.get_pc(), 4) - imm32;
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
}
this.print_inst_imm(addr, inst, "adr", null, d, null, imm32);
};
ARMv7_CPU.prototype.and_imm = function(inst, addr) {
this.print_inst("AND (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var valn = this.reg(n);
var ret = bitops.and(valn, imm32);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "and", s, d, n, imm32);
};
ARMv7_CPU.prototype.asr_imm = function(inst, addr) {
this.print_inst("ASR (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var m = inst & 0xf;
this.decode_imm_shift(2, imm5);
var ret = this.shift_c(this.reg(m), this.SRType_ASR, this.shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "asr", s, d, m, imm5);
};
ARMv7_CPU.prototype.bic_imm = function(inst, addr) {
this.print_inst("BIC (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = bitops.and(valn, bitops.not(imm32));
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "bic", s, d, n, bitops.sint32(imm32));
};
ARMv7_CPU.prototype.b = function(inst, addr) {
this.print_inst("B", inst, addr);
var imm24 = inst & 0x00ffffff;
//imm32 = SignExtend(imm24:'00', 32);
//var imm32 = bitops.sign_extend(imm24 << 2, 26, 32);
var imm26 = imm24 << 2;
var imm32 = imm26;
if (imm26 & 0x02000000)
imm32 = imm26 | 0xfc000000;
this.branch_to = this.get_pc() + imm32;
if (this.branch_to >= 0x100000000)
this.branch_to -= 0x100000000;
this.print_inst_branch(addr, inst, "b", this.branch_to);
};
ARMv7_CPU.prototype.bl_imm = function(inst, addr) {
this.print_inst("BL, BLX (immediate)", inst, addr);
//var imm24 = bitops.get_bits(inst, 23, 0);
//var imm32 = bitops.sign_extend(imm24 << 2, 26, 32);
var imm24 = inst & 0x00ffffff;
var imm26 = imm24 << 2;
var imm32 = imm26;
if (imm26 & 0x02000000)
imm32 = imm26 | 0xfc000000;
this.regs[14] = this.get_pc() - 4;
// BranchWritePC(Align(PC,4) + imm32);
this.branch_to = this.align(bitops.lsl((this.get_pc()) >>> 2, 2), 4) + imm32;
if (this.branch_to >= 0x100000000)
this.branch_to -= 0x100000000;
this.print_inst_branch(addr, inst, "bl", this.branch_to);
};
ARMv7_CPU.prototype.cmn_imm = function(inst, addr) {
this.print_inst("CMN (immediate)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm(imm12);
var ret = this.add_with_carry(valn, imm32, 0);
this.set_apsr(ret, true);
this.print_inst_imm(addr, inst, "cmn", null, null, n, imm32);
};
ARMv7_CPU.prototype.cmp_imm = function(inst, addr) {
this.print_inst("CMP (immediate)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm(imm12);
var ret = this.add_with_carry(valn, bitops.not(imm32), 1);
this.set_apsr(ret, true);
this.print_inst_imm(addr, inst, "cmp", null, null, n, imm32);
};
ARMv7_CPU.prototype.eor_imm = function(inst, addr) {
this.print_inst("EOR (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var valn = this.reg(n);
var ret = bitops.xor(valn, imm32);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "eor", s, d, n, imm32);
};
ARMv7_CPU.prototype.ldr_imm = function(inst, addr) {
this.print_inst("LDR (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm12 = (inst & 0xfff);
if (n == 13 && p === 0 && u == 1 && w === 0 && imm12 === 4) {
// POP A2
if (t == 15)
this.branch_to = this.ld_word(this.regs[13]);
else
this.regs[t] = this.ld_word(this.regs[13]);
this.regs[13] = this.regs[13] + 4;
this.print_inst_unimpl(addr, inst, "pop");
return;
}
var imm32 = imm12;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
var data = this.ld_word(address);
if (is_wback)
this.regs[n] = offset_addr;
if (t == 15)
this.branch_to = data;
else
this.regs[t] = data;
this.print_inst_imm(addr, inst, "ldr", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.ldrb_imm = function(inst, addr) {
this.print_inst("LDRB (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm32 = inst & 0xfff;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
var data = this.ld_byte(address);
this.regs[t] = data;
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "ldrb", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.ldrd_imm = function(inst, addr) {
this.print_inst("LDRD (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var t2 = t + 1;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
this.regs[t] = this.ld_word(address);
this.regs[t2] = this.ld_word(address+4);
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "ldrd", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.ldrsh_imm = function(inst, addr) {
this.print_inst("LDRSH (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
var data = this.ld_halfword(address);
if (is_wback)
this.regs[n] = offset_addr;
this.regs[t] = bitops.sign_extend(data, 16, 32);
this.print_inst_imm(addr, inst, "ldrsh", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.ldrsh_reg = function(inst, addr) {
this.print_inst("LDRSH (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset = this.shift(this.reg(m), this.SRType_LSL, 0, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
var data = this.ld_halfword(address);
if (is_wback)
this.regs[n] = offset_addr;
this.regs[t] = bitops.sign_extend(data, 16, 32);
this.print_inst_reg(addr, inst, "ldrsh", null, t, n, m, this.SRType_LSL, 0);
};
ARMv7_CPU.prototype.lsl_imm = function(inst, addr) {
this.print_inst("LSL (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var m = inst & 0xf;
var valm = this.reg(m);
this.decode_imm_shift(0, imm5);
var ret = this.shift_c(valm, this.SRType_LSL, this.shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "lsl", s, d, m, imm5);
};
ARMv7_CPU.prototype.lsr_imm = function(inst, addr) {
this.print_inst("LSR (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var m = inst & 0xf;
var valm = this.reg(m);
this.decode_imm_shift(1, imm5);
var ret = this.shift_c(valm, this.SRType_LSR, this.shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "lsr", s, d, m, imm5);
};
ARMv7_CPU.prototype.mov_imm_a1 = function(inst, addr) {
this.print_inst("MOV (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = imm32;
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "mov", s, d, null, imm32);
};
ARMv7_CPU.prototype.mov_imm_a2 = function(inst, addr) {
this.print_inst("MOV (immediate) A2", inst, addr);
var imm4 = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = (imm4 << 12) + imm12;
var ret = imm32;
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
}
this.print_inst_imm(addr, inst, "movw", false, d, null, imm32);
};
ARMv7_CPU.prototype.movt = function(inst, addr) {
this.print_inst("MOVT", inst, addr);
var imm4 = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm16 = (imm4 << 12) + imm12;
this.regs[d] = bitops.set_bits(this.reg(d), 16, 31, imm16);
//this.print_inst_imm(addr, inst, "movw", false, d, null, imm32);
};
ARMv7_CPU.prototype.msr_imm_sys = function(inst, addr) {
this.print_inst("MSR (immediate) (system level)", inst, addr);
var r = inst & (1 << 22);
var mask = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
if (r) {
// SPSRWriteByInstr(R[n], mask);
this.spsr_write_by_instr(this.parse_psr(imm32), mask);
} else {
// CPSRWriteByInstr(R[n], mask, FALSE);
this.cpsr_write_by_instr(this.parse_psr(imm32), mask, false);
}
this.print_inst_msr(addr, inst, null, imm32);
};
ARMv7_CPU.prototype.mvn_imm = function(inst, addr) {
this.print_inst("MVN (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = bitops.not(imm32);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "mvn", s, d, null, imm32);
};
ARMv7_CPU.prototype.orr_imm = function(inst, addr) {
this.print_inst("ORR (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = bitops.or(valn, imm32);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "orr", s, d, n, imm32);
};
ARMv7_CPU.prototype.hint_preload_data = function(address) {
// FIXME
this.log_value(address, "preload address");
};
ARMv7_CPU.prototype.pld_imm = function(inst, addr) {
this.print_inst("PLD (immediate, literal)", inst, addr);
var u = (inst >>> 23) & 1;
var n = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = imm12;
var is_add = u == 1;
var base = (n == 15) ? this.align(this.get_pc(), 4) : valn;
var address = base + (is_add ? imm32 : -imm32);
this.hint_preload_data(address);
this.print_inst_imm(addr, inst, "pld", null, null, n, imm32, true, null, is_add, true);
};
ARMv7_CPU.prototype.rsb_imm = function(inst, addr) {
this.print_inst("RSB (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var valn = this.reg(n);
var ret = this.add_with_carry(bitops.not(valn), imm32, 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "rsb", s, d, n, imm32);
};
ARMv7_CPU.prototype.rsc_imm = function(inst, addr) {
this.print_inst("RSC (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var valn = this.reg(n);
var ret = this.add_with_carry(bitops.not(valn), imm32, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "rsc", s, d, n, imm32);
};
ARMv7_CPU.prototype.ror_imm = function(inst, addr) {
this.print_inst("ROR (immediate)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var m = inst & 0xf;
var valm = this.reg(m);
this.decode_imm_shift(3, imm5);
var ret = this.shift_c(valm, this.SRType_ROR, this.shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_imm(addr, inst, "ror", s, d, m, imm5);
};
ARMv7_CPU.prototype.rrx = function(inst, addr) {
this.print_inst("RRX", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var valm = this.reg(m);
var ret = this.shift_c(valm, this.SRType_RRX, 1, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
//this.print_inst_imm(addr, inst, "rrx", s, d, m, null);
this.print_inst_unimpl(addr, inst, "rrx");
};
ARMv7_CPU.prototype.sbc_imm = function(inst, addr) {
this.print_inst("SBC (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var valn = this.reg(n);
var ret = this.add_with_carry(valn, bitops.not(imm32), this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "sbc", s, d, n, imm32);
};
ARMv7_CPU.prototype.str_imm = function(inst, addr) {
this.print_inst("STR (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var address;
if (n == 13 && p == 1 && u === 0 && w == 1 && imm12 == 4) {
// PUSH A2
var sp = this.reg(13);
address = sp - 4;
this.st_word(address, this.reg(t));
this.regs[13] = sp - 4;
return;
}
var imm32 = imm12;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
address = is_index ? offset_addr : valn;
var valt = this.reg(t);
this.st_word(address, valt);
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "str", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.strb_imm = function(inst, addr) {
this.print_inst("STRB (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm32 = inst & 0xfff;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn= this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
this.st_byte(address, this.reg(t) & 0xff);
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "strb", null, t, n, imm32, true, is_wback, is_add, is_index);
};
ARMv7_CPU.prototype.sub_imm = function(inst, addr) {
this.print_inst("SUB (immediate)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm12 = inst & 0xfff;
var imm32 = this.expand_imm(imm12);
var ret = this.add_with_carry(this.reg(n), bitops.not(imm32), 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_imm(addr, inst, "sub", s, d, n, imm32);
};
ARMv7_CPU.prototype.teq_imm = function(inst, addr) {
this.print_inst("TEQ (immediate)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = bitops.xor(valn, imm32);
this.set_apsr(ret, false);
this.print_inst_imm(addr, inst, "teq", null, null, n, imm32);
};
ARMv7_CPU.prototype.tst_imm = function(inst, addr) {
this.print_inst("TST (immediate)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm12 = inst & 0xfff;
var valn = this.reg(n);
var imm32 = this.expand_imm_c(imm12, this.cpsr.c);
var ret = bitops.and(valn, imm32);
this.set_apsr(ret, false);
this.print_inst_imm(addr, inst, "tst", null, null, n, imm32);
};
/*
* Literal
*/
ARMv7_CPU.prototype.ldr_lit = function(inst, addr) {
this.print_inst("LDR (literal)", inst, addr);
var u = inst & (1 << 23);
var t = (inst >>> 12) & 0xf;
var imm32 = inst & 0xfff;
var base = this.align(this.get_pc(), 4);
var address = base + (u ? imm32 : -imm32);
var data = this.ld_word(address);
if (t == 15)
this.branch_to = data;
else
this.regs[t] = data;
this.print_inst_imm(addr, inst, "ldr", null, t, 15, imm32, true, null, u, true);
};
/*
* Register
*/
ARMv7_CPU.prototype.adc_reg = function(inst, addr) {
this.print_inst("ADC (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, shifted, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_reg(addr, inst, "adc", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.add_reg = function(inst, addr) {
this.print_inst("ADD (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, shifted, 0);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_reg(addr, inst, "add", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.and_reg = function(inst, addr) {
this.print_inst("AND (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.and(valn, shifted);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "and", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.asr_reg = function(inst, addr) {
this.print_inst("ASR (register)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var shift_n = bitops.get_bits(this.reg(m), 7, 0);
var ret = this.shift_c(this.reg(n), this.SRType_ASR, shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "asr", s, d, n, m);
};
ARMv7_CPU.prototype.bic_reg = function(inst, addr) {
this.print_inst("BIC (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.and(valn, bitops.not(shifted));
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "bic", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.bfc = function(inst, addr) {
this.print_inst("BFC", inst, addr);
var msbit = (inst >>> 16) & 0x1f;
var d = (inst >>> 12) & 0xf;
var lsbit = (inst >>> 7) & 0x1f;
if (msbit >= lsbit)
this.regs[d] = bitops.clear_bits(this.regs[d], msbit, lsbit);
else
this.abort_unpredictable("BFC", inst, addr);
this.print_inst_ubfx(addr, inst, "bfc", d, null, msbit, lsbit);
};
ARMv7_CPU.prototype.bfi = function(inst, addr) {
this.print_inst("BFI", inst, addr);
var msbit = (inst >>> 16) & 0x1f;
var d = (inst >>> 12) & 0xf;
var lsbit = (inst >>> 7) & 0x1f;
var n = inst & 0xf;
if (msbit >= lsbit)
this.regs[d] = bitops.set_bits(this.regs[d], msbit, lsbit, bitops.get_bits(this.reg(n), msbit-lsbit, 0));
else
this.abort_unpredictable("BFI", inst, addr);
this.print_inst_ubfx(addr, inst, "bfi", d, n, msbit, lsbit);
};
ARMv7_CPU.prototype.blx_reg = function(inst, addr) {
this.print_inst("BLX (register)", inst, addr);
var m = inst & 0xf;
var next_instr_addr = this.get_pc() - 4;
this.regs[14] = next_instr_addr;
this.branch_to = this.reg(m);
//this.print_inst_reg(addr, inst, "blx", null, null, null, m);
this.print_inst_branch(addr, inst, "blx", this.branch_to, m);
};
ARMv7_CPU.prototype.bx = function(inst, addr) {
this.print_inst("BX", inst, addr);
var m = inst & 0xf;
this.branch_to = this.reg(m);
this.print_inst_branch(addr, inst, "bx", this.branch_to, m);
};
ARMv7_CPU.prototype.cdp_a1 = function(inst, addr) {
this.print_inst("CDP, CDP2 A1?", inst, addr);
var t = (inst >>> 12) & 0xf;
var cp = (inst >>> 8) & 0xf;
if ((cp >> 1) == 5) {
this.abort_simdvfp_inst(inst, addr);
}
if (!this.coproc_accepted(cp)) {
throw "GenerateCoprocessorException(): " + cp;
} else {
this.coproc_internal_operation(cp, inst);
}
//this.print_inst_mcrmrc(inst, "cdp", t, cp);
this.print_inst_unimpl(addr, inst, "cdp");
};
ARMv7_CPU.prototype.clz = function(inst, addr) {
this.print_inst("CLZ", inst, addr);
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
this.regs[d] = bitops.count_leading_zero_bits(this.reg(m));
this.print_inst_reg(addr, inst, "clz", null, d, null, m);
};
ARMv7_CPU.prototype.cmn_reg = function(inst, addr) {
this.print_inst("CMN (register)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, shifted, 0);
this.set_apsr(ret, true);
this.print_inst_reg(addr, inst, "cmn", null, null, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.cmp_reg = function(inst, addr) {
this.print_inst("CMP (register)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, bitops.not(shifted), 1);
this.set_apsr(ret, true);
this.print_inst_reg(addr, inst, "cmp", null, null, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.eor_reg = function(inst, addr) {
this.print_inst("EOR (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.xor(valn, shifted);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "eor", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.ldr_reg = function(inst, addr) {
this.print_inst("LDR (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
this.decode_imm_shift(type, imm5);
var offset = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
address = bitops.get_bits64(address, 31, 0); // XXX
var data = this.ld_word(address);
if (is_wback)
this.regs[n] = offset_addr;
if (t == 15)
this.branch_to = data;
else
this.regs[t] = data;
this.print_inst_reg(addr, inst, "ldr", null, t, n, m, this.shift_t, this.shift_n, true, is_wback);
};
ARMv7_CPU.prototype.ldrb_reg = function(inst, addr) {
this.print_inst("LDRB (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
this.decode_imm_shift(type, imm5);
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
var data = this.ld_byte(address);
this.regs[t] = data;
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "ldrb", null, t, n, m, this.shift_t, this.shift_n, true, is_wback, is_index);
};
ARMv7_CPU.prototype.ldrd_reg = function(inst, addr) {
this.print_inst("LDRD (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var t2 = t + 1;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var valm = this.reg(m);
var offset_addr = valn + (is_add ? valm : -valm);
var address = is_index ? offset_addr : valn;
this.regs[t] = this.ld_word(address);
this.regs[t2] = this.ld_word(address + 4);
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "ldrd", null, t, n, m, null, null, true, is_wback, is_index);
};
ARMv7_CPU.prototype.ldrex = function(inst, addr) {
this.print_inst("LDREX", inst, addr);
var n = bitops.get_bits(inst, 19, 16);
var t = bitops.get_bits(inst, 15, 12);
var imm32 = 0;
var address = this.reg(n) + imm32;
// SetExclusiveMonitors(address,4);
// R[t] = MemA[address,4];
this.regs[t] = this.ld_word(address);
this.print_inst_reg(addr, inst, "ldrex", null, t, n, null, null, null, true, false);
};
ARMv7_CPU.prototype.ldrexd = function(inst, addr) {
this.print_inst("LDREXD", inst, addr);
var n = bitops.get_bits(inst, 19, 16);
var t = bitops.get_bits(inst, 15, 12);
var t2 = t + 1;
var address = this.reg(n);
// SetExclusiveMonitors(address,8);
// value = MemA[address,8];
// R[t] = value<31:0>
// R[t2] = value<63:31>
this.regs[t] = this.ld_word(address);
this.regs[t2] = this.ld_word(address + 4);
this.print_inst_reg(addr, inst, "ldrexd", null, t, n, null, null, null, true, false);
};
ARMv7_CPU.prototype.ldrt_a1 = function(inst, addr) {
this.print_inst("LDRT A1", inst, addr);
var u = (inst >>> 23) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm32 = inst & 0xfff;
var is_add = u == 1;
var valn = this.reg(n);
var offset = imm32;
var offset_addr = valn + (is_add ? offset : -offset);
var address = valn;
address = bitops.get_bits64(address, 31, 0); // XXX
var data = this.ld_word(address);
if (t == 15)
this.branch_to = data;
else
this.regs[t] = data;
//this.print_inst_reg(addr, inst, "ldrt", null, t, n, m, this.shift_t, this.shift_n, true, is_wback);
};
ARMv7_CPU.prototype.lsl_reg = function(inst, addr) {
this.print_inst("LSL (register)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var shift_n = bitops.get_bits(this.reg(m), 7, 0);
var ret = this.shift_c(this.reg(n), this.SRType_LSL, shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "lsl", s, d, n, m);
};
ARMv7_CPU.prototype.lsr_reg = function(inst, addr) {
this.print_inst("LSR (register)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var shift_n = bitops.get_bits(this.reg(m), 7, 0);
var ret = this.shift_c(this.reg(n), this.SRType_LSR, shift_n, this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "lsr", s, d, n, m);
};
ARMv7_CPU.prototype.mcr_a1 = function(inst, addr) {
this.print_inst("MCR, MCR2 A1", inst, addr);
var t = (inst >>> 12) & 0xf;
var cp = (inst >>> 8) & 0xf;
if ((cp >> 1) == 5) {
this.abort_simdvfp_inst(inst, addr);
}
if (!this.coproc_accepted(cp)) {
throw "GenerateCoprocessorException()";
} else {
this.coproc_send_word(cp, inst, this.regs[t]);
}
this.print_inst_mcrmrc(addr, inst, "mcr", t, cp);
};
ARMv7_CPU.prototype.mla = function(inst, addr) {
this.print_inst("MLA", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 16) & 0xf;
var a = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var ope1 = this.reg(n);
var ope2 = this.reg(m);
var addend = this.reg(a);
var n64_ope1 = new Number64(0, ope1);
var n64_ope2 = new Number64(0, ope2);
var n64_addend = new Number64(0, addend);
var n64 = n64_ope1.mul(n64_ope2);
var ret = n64.add(n64_addend);
this.regs[d] = ret.low;
if (s) {
this.cpsr.n = (ret.low >>> 31) & 1;
this.cpsr.z = (ret === 0) ? 1 : 0;
this.log_apsr();
}
this.print_inst_reg(addr, inst, "mla", s, d, n, m); // FIXME
};
ARMv7_CPU.prototype.mls = function(inst, addr) {
this.print_inst("MLS", inst, addr);
var d = (inst >>> 16) & 0xf;
var a = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var ope1 = this.reg(n);
var ope2 = this.reg(m);
var addend = this.reg(a);
var n64_ope1 = new Number64(0, ope1);
var n64_ope2 = new Number64(0, ope2);
var n64_addend = new Number64(0, addend);
var n64 = n64_ope1.mul(n64_ope2);
var ret = n64_addend.sub(n64);
this.regs[d] = ret.low;
this.print_inst_mul(addr, inst, "mls", null, n, d, m, a);
};
ARMv7_CPU.prototype.subs_pc_lr_a2 = function(inst, addr) {
var opcode = (inst >>> 21) & 0xf;
var n = (inst >>> 16) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
this.decode_imm_shift(type, imm5);
var operand2 = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var ret;
switch (opcode) {
case 0:
ret = bitops.and(this.reg(n), operand2);
break;
case 1:
ret = bitops.xor(this.reg(n), operand2);
break;
case 2:
ret = this.add_with_carry(this.reg(n), bitops.not(operand2), 1);
break;
case 3:
ret = this.add_with_carry(bitops.not(this.reg(n)), operand2, 1);
break;
case 4:
ret = this.add_with_carry(this.reg(n), operand2, 0);
break;
case 5:
ret = this.add_with_carry(this.reg(n), operand2, this.cpsr.c);
break;
case 6:
ret = this.add_with_carry(this.reg(n), bitops.not(operand2), this.cpsr.c);
break;
case 7:
ret = this.add_with_carry(bitops.not(this.reg(n)), operand2, this.cpsr.c);
break;
case 0xc:
ret = bitops.or(this.reg(n), operand2);
break;
case 0xd:
ret = operand2;
break;
case 0xe:
ret = bitops.and(this.reg(n), bitops.not(operand2));
break;
case 0xf:
ret = bitops.not(operand2);
break;
default:
throw "subs_pc_lr_a2: unknown opcode";
break;
}
this.cpsr_write_by_instr(this.get_current_spsr(), 15, true);
this.branch_to = ret;
this.print_inst_unimpl(addr, inst, "subs");
};
ARMv7_CPU.prototype.mov_reg = function(inst, addr) {
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
if (d == 15 && s) {
this.print_inst("SUBS PC LR A2", inst, addr);
this.subs_pc_lr_a2(inst, addr);
return;
}
var ret = this.reg(m);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s) {
this.cpsr.n = ret >>> 31;
this.cpsr.z = (ret === 0) ? 1 : 0;
// FIXME: APSR.C = carry;
// I guess carry == 0
//this.cpsr.c(bitops.get_bit(value, 29));
//this.abort_not_impl("MOV (register) flag", inst, addr);
this.log_apsr();
}
}
this.print_inst_reg(addr, inst, "mov", s, d, null, m);
};
ARMv7_CPU.prototype.mrc_a1 = function(inst, addr) {
var t = (inst >>> 12) & 0xf;
var cp = (inst >>> 8) & 0xf;
if ((cp >> 1) == 5) {
this.abort_simdvfp_inst(inst, addr);
}
if (!this.coproc_accepted(cp)) {
throw "GenerateCoprocessorException()";
} else {
var value = this.coproc_get_word(cp, inst);
if (t != 15) {
this.regs[t] = value;
} else {
this.cpsr.n = (value >>> 31) & 1;
this.cpsr.z = (value >>> 30) & 1;
this.cpsr.c = (value >>> 29) & 1;
this.cpsr.v = (value >>> 28) & 1;
this.log_apsr();
}
}
this.print_inst_mcrmrc(addr, inst, "mrc", t, cp);
};
ARMv7_CPU.prototype.mrs = function(inst, addr) {
this.print_inst("MRS", inst, addr);
var read_spsr = inst & (1 << 22);
var d = (inst >>> 12) & 0xf;
if (read_spsr) {
if (this.is_user_or_system())
this.abort_unpredictable("MRS", inst, addr);
else
this.regs[d] = this.psr_to_value(this.get_current_spsr());
} else {
// CPSR AND '11111000 11111111 00000011 11011111'
this.regs[d] = bitops.and(this.psr_to_value(this.cpsr), 0xf8ff03df);
}
this.print_inst_mrs(addr, inst, d);
};
ARMv7_CPU.prototype.msr_reg_sys = function(inst, addr) {
this.print_inst("MSR (register) (system level)", inst, addr);
var r = inst & (1 << 22);
var mask = (inst >>> 16) & 0xf;
var n = inst & 0xf;
if (r) {
// SPSRWriteByInstr(R[n], mask);
this.spsr_write_by_instr(this.parse_psr(this.reg(n)), mask);
} else {
// CPSRWriteByInstr(R[n], mask, FALSE);
this.cpsr_write_by_instr(this.parse_psr(this.reg(n)), mask, false);
}
this.print_inst_msr(addr, inst, n);
};
ARMv7_CPU.prototype.mul = function(inst, addr) {
this.print_inst("MUL", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 16) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var ope1 = this.reg(n);
var ope2 = this.reg(m);
var n64_ope1 = new Number64(0, ope1);
var n64_ope2 = new Number64(0, ope2);
var ret = n64_ope1.mul(n64_ope2);
this.regs[d] = ret.low;
if (s) {
//this.cpsr.n = bitops.get_bit(ret.low, 31);
this.cpsr.n = ret.low >>> 31;
this.cpsr.z = (ret === 0) ? 1 : 0;
this.log_apsr();
}
this.print_inst_reg(addr, inst, "mul", s, d, n, m); // FIXME
};
ARMv7_CPU.prototype.mvn_reg = function(inst, addr) {
this.print_inst("MVN (register)", inst, addr);
var s = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.not(shifted);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "mvn", s, d, null, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.orr_reg = function(inst, addr) {
this.print_inst("ORR (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.or(valn, shifted);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, false);
}
this.print_inst_reg(addr, inst, "orr", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.rev = function(inst, addr) {
this.print_inst("REV", inst, addr);
var d = bitops.get_bits(inst, 15, 12);
var m = bitops.get_bits(inst, 3, 0);
var valm = this.reg(m);
var ret = 0;
ret = bitops.set_bits(ret, 31, 24, bitops.get_bits(valm, 7, 0));
ret = bitops.set_bits(ret, 23, 16, bitops.get_bits(valm, 15, 8));
ret = bitops.set_bits(ret, 15, 8, bitops.get_bits(valm, 23, 16));
ret = bitops.set_bits(ret, 7, 0, bitops.get_bits(valm, 31, 24));
this.regs[d] = ret;
this.print_inst_reg(addr, inst, "rev", null, d, null, m);
};
ARMv7_CPU.prototype.rev16 = function(inst, addr) {
this.print_inst("REV16", inst, addr);
var d = bitops.get_bits(inst, 15, 12);
var m = bitops.get_bits(inst, 3, 0);
var valm = this.reg(m);
var ret = 0;
ret = bitops.set_bits(ret, 31, 24, bitops.get_bits(valm, 23, 16));
ret = bitops.set_bits(ret, 23, 16, bitops.get_bits(valm, 31, 24));
ret = bitops.set_bits(ret, 15, 8, bitops.get_bits(valm, 7, 0));
ret = bitops.set_bits(ret, 7, 0, bitops.get_bits(valm, 15, 8));
this.regs[d] = ret;
this.print_inst_reg(addr, inst, "rev16", null, d, null, m);
};
ARMv7_CPU.prototype.rsb_reg = function(inst, addr) {
this.print_inst("RSB (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(bitops.not(valn), shifted, 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_reg(addr, inst, "rsb", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.sbc_reg = function(inst, addr) {
this.print_inst("SBC (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, bitops.not(shifted), this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_reg(addr, inst, "sbc", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.sbfx = function(inst, addr) {
this.print_inst("SBFX", inst, addr);
var widthminus1 = (inst >>> 16) & 0x1f;
var d = (inst >>> 12) & 0xf;
var lsbit = (inst >>> 7) & 0x1f;
var n = inst & 0xf;
var msbit = lsbit + widthminus1;
if (msbit <= 31)
this.regs[d] = bitops.sign_extend(bitops.get_bits(this.reg(n), msbit, lsbit), msbit-lsbit+1, 32);
else
this.abort_unpredictable("SBFX", inst, addr);
this.print_inst_ubfx(addr, inst, "sbfx", d, n, lsbit, widthminus1 + 1);
};
ARMv7_CPU.prototype.smlal = function(inst, addr) {
this.print_inst("SMLAL", inst, addr);
var s = inst & 0x00100000;
var dhi = (inst >>> 16) & 0xf;
var dlo = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var n64_n = new Number64(0, this.reg(n));
var n64_m = new Number64(0, this.reg(m));
var n64 = new Number64(this.reg(dhi), this.reg(dlo));
var ret = n64_n.mul(n64_m).add(n64);
this.regs[dhi] = ret.high;
this.regs[dlo] = ret.low;
if (s) {
this.cpsr.n = bitops.get_bit(ret.high, 31);
this.cpsr.z = ret.is_zero() ? 1 : 0;
this.log_apsr();
}
this.print_inst_mul(addr, inst, "smlal", s, dhi, dlo, n, m);
};
ARMv7_CPU.prototype.smull = function(inst, addr) {
this.print_inst("SMULL", inst, addr);
var s = inst & 0x00100000;
var dhi = (inst >>> 16) & 0xf;
var dlo = (inst >>> 12) & 0xf;
var m = (inst >>> 8) & 0xf;
var n = inst & 0xf;
var n64_n = new Number64(0, this.reg(n));
var n64_m = new Number64(0, this.reg(m));
var ret = n64_n.mul(n64_m);
this.regs[dhi] = ret.high;
this.regs[dlo] = ret.low;
if (s) {
this.cpsr.n = bitops.get_bit(ret.high, 31);
this.cpsr.z = ret.is_zero() ? 1 : 0;
this.log_apsr();
}
this.print_inst_mul(addr, inst, "smull", s, dhi, dlo, n, m);
};
ARMv7_CPU.prototype.swp = function(inst,addr){
this.print_inst("SWP(B?)", inst, addr);
var B = (inst >> 22) & 0x1;
var Rn = (inst >> 16) & 0xF;
var Rd = (inst >> 12) & 0xF;
var Rm = inst & 0xF;
var valn = this.reg(Rn);
var valm = this.reg(Rm);
address = valn;
if(B){
var data = this.ld_byte(address);
this.st_byte(address, bitops.get_bits(valm, 7, 0));
this.regs[Rd] = data;
} else {
var data = this.ld_word(address);
this.st_word(address, valm);
this.regs[Rd] = data;
}
this.print_inst_reg(addr, inst, "swp"+B?"B":"", null, Rn, Rd, Rm, null, null, false, false);
};
ARMv7_CPU.prototype.strex = function(inst, addr) {
this.print_inst("STREX", inst, addr);
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var t = inst & 0xf;
var imm32 = 0;
var address = this.reg(n) + imm32;
// ExclusiveMonitorsPass(address,4)
this.st_word(address, this.reg(t));
this.regs[d] = 0;
// FIXME
this.print_inst_reg(addr, inst, "strex", null, t, n, d, null, null, true, false);
};
ARMv7_CPU.prototype.strexd = function(inst, addr) {
this.print_inst("STREXD", inst, addr);
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var t = inst & 0xf;
var t2 = t + 1;
var address = this.reg(n);
// ExclusiveMonitorsPass(address,8)
this.st_word(address, this.reg(t));
this.st_word(address + 4, this.reg(t2));
this.regs[d] = 0;
// FIXME
this.print_inst_reg(addr, inst, "strexd", null, t, n, d, null, null, true, false);
};
ARMv7_CPU.prototype.sub_reg = function(inst, addr) {
this.print_inst("SUB (register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.add_with_carry(valn, bitops.not(shifted), 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (s)
this.set_apsr(ret, true);
}
this.print_inst_reg(addr, inst, "sub", s, d, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.sxtb = function(inst, addr) {
this.print_inst("SXTB", inst, addr);
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = bitops.sign_extend(bitops.get_bits64(rotated, 7, 0), 8, 32);
this.print_inst_reg(addr, inst, "sxtb", null, d, null, m);
};
ARMv7_CPU.prototype.sxth = function(inst, addr) {
this.print_inst("SXTH", inst, addr);
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = bitops.sign_extend(bitops.get_bits64(rotated, 15, 0), 16, 32);
this.print_inst_reg(addr, inst, "sxth", null, d, null, m);
};
ARMv7_CPU.prototype.sxtah = function(inst, addr) {
this.print_inst("SXTAH", inst, addr);
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
var n64 = new Number64(0, this.reg(n));
this.regs[d] = n64.add(bitops.sign_extend(bitops.get_bits64(rotated, 15, 0), 16, 32)).low;
this.print_inst_reg(addr, inst, "sxtah", null, d, null, m);
};
ARMv7_CPU.prototype.teq_reg = function(inst, addr) {
this.print_inst("TEQ (register)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var valn = this.reg(n);
var valm = this.reg(m);
this.decode_imm_shift(type, imm5);
var shifted = this.shift(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.xor(valn, shifted);
this.set_apsr(ret, false);
this.print_inst_reg(addr, inst, "teq", null, null, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.tst_reg = function(inst, addr) {
this.print_inst("TST (register)", inst, addr);
var n = (inst >>> 16) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
this.decode_imm_shift(type, imm5);
var valn = this.reg(n);
var valm = this.reg(m);
var shifted = this.shift_c(valm, this.shift_t, this.shift_n, this.cpsr.c);
var ret = bitops.and(valn, shifted);
this.set_apsr(ret, false);
this.print_inst_reg(addr, inst, "tst", null, null, n, m, this.shift_t, this.shift_n);
};
ARMv7_CPU.prototype.ubfx = function(inst, addr) {
this.print_inst("UBFX", inst, addr);
var widthminus1 = bitops.get_bits(inst, 20, 16);
var d = bitops.get_bits(inst, 15, 12);
var lsbit = bitops.get_bits(inst, 11, 7);
var n = bitops.get_bits(inst, 3, 0);
var msbit = lsbit + widthminus1;
if (msbit <= 31)
this.regs[d] = bitops.get_bits(this.reg(n), msbit, lsbit);
else
this.abort_unpredictable("UBFX", inst, addr);
this.print_inst_ubfx(addr, inst, "ubfx", d, n, lsbit, widthminus1 + 1);
};
ARMv7_CPU.prototype.umlal = function(inst, addr) {
this.print_inst("UMLAL", inst, addr);
var s = inst & 0x00100000;
var dhi = bitops.get_bits(inst, 19, 16);
var dlo = bitops.get_bits(inst, 15, 12);
var m = bitops.get_bits(inst, 11, 8);
var n = bitops.get_bits(inst, 3, 0);
var n64_n = new Number64(0, this.reg(n));
var n64_m = new Number64(0, this.reg(m));
var n64_d = new Number64(this.reg(dhi), this.reg(dlo));
var ret = n64_n.mul(n64_m).add(n64_d);
this.regs[dhi] = ret.high;
this.regs[dlo] = ret.low;
if (s) {
this.cpsr.n = bitops.get_bit(ret.high, 31);
this.cpsr.z = ret.is_zero() ? 1 : 0;
this.log_apsr();
}
this.print_inst_mul(addr, inst, "umlal", s, dhi, dlo, n, m);
};
ARMv7_CPU.prototype.umull = function(inst, addr) {
this.print_inst("UMULL", inst, addr);
var s = inst & 0x00100000;
var dhi = bitops.get_bits(inst, 19, 16);
var dlo = bitops.get_bits(inst, 15, 12);
var m = bitops.get_bits(inst, 11, 8);
var n = bitops.get_bits(inst, 3, 0);
var n64_n = new Number64(0, this.reg(n));
var n64_m = new Number64(0, this.reg(m));
var ret = n64_n.mul(n64_m);
this.regs[dhi] = ret.high;
this.regs[dlo] = ret.low;
if (s) {
this.cpsr.n = bitops.get_bit(ret.high, 31);
this.cpsr.z = ret.is_zero() ? 1 : 0;
this.log_apsr();
}
this.print_inst_mul(addr, inst, "umull", s, dhi, dlo, n, m);
};
ARMv7_CPU.prototype.unsigned_satq = function(i, n) {
var ret;
if (i > (Math.pow(2, n) - 1)) {
ret = Math.pow(2, n) - 1;
this.saturated = true;
} else if (i < 0) {
ret = 0;
this.saturated = true;
} else {
ret = i;
this.saturated = false;
}
return bitops.get_bits64(ret, 31, 0);
};
ARMv7_CPU.prototype.usat = function(inst, addr) {
this.print_inst("USAT", inst, addr);
var saturate_to = bitops.get_bits(inst, 20, 16);
var d = bitops.get_bits(inst, 15, 12);
var imm5 = bitops.get_bits(inst, 11, 7);
var sh = bitops.get_bit(inst, 6);
var n = bitops.get_bits(inst, 3, 0);
this.decode_imm_shift(sh << 1, imm5);
var operand = this.shift(this.reg(n), this.shift_t, this.shift_n, this.cpsr.c);
var ret = this.unsigned_satq(this.sint32(operand), saturate_to);
this.regs[n] = ret;
if (this.saturated)
this.cpsr.q = 1;
this.print_inst_unimpl(addr, inst, "usat");
};
ARMv7_CPU.prototype.uxtab = function(inst, addr) {
this.print_inst("UXTAB", inst, addr);
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var m = inst & 0xf;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = this.reg(n) + bitops.get_bits64(rotated, 7, 0);
this.print_inst_uxtab(addr, inst, "uxtab", d, n, m, rotation);
};
ARMv7_CPU.prototype.uxtah = function(inst, addr) {
this.print_inst("UXTAH", inst, addr);
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = this.reg(n) + bitops.get_bits64(rotated, 15, 0);
this.print_inst_uxtab(addr, inst, "uxtah", d, null, m, rotation);
};
ARMv7_CPU.prototype.uxtb = function(inst, addr) {
this.print_inst("UXTB", inst, addr);
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = bitops.get_bits64(rotated, 7, 0);
this.print_inst_uxtab(addr, inst, "uxtb", d, null, m, rotation);
};
ARMv7_CPU.prototype.uxth = function(inst, addr) {
this.print_inst("UXTH", inst, addr);
var d = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var rotation = ((inst >>> 10) & 3) << 3;
var rotated = this.ror(this.reg(m), rotation);
this.regs[d] = bitops.get_bits64(rotated, 15, 0);
this.print_inst_uxtab(addr, inst, "uxth", d, null, m, rotation);
};
/*
* Register-shifted Register
*/
ARMv7_CPU.prototype.add_rsr = function(inst, addr) {
this.print_inst("ADD (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = this.add_with_carry(this.reg(n), shifted, 0);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, true);
}
this.print_inst_rsr(addr, inst, "add", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.and_rsr = function(inst, addr) {
this.print_inst("AND (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.and(this.reg(n), shifted);
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, false);
this.print_inst_rsr(addr, inst, "and", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.bic_rsr = function(inst, addr) {
this.print_inst("BIC (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.and(this.reg(n), bitops.not(shifted));
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, false);
}
this.print_inst_rsr(addr, inst, "bic", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.cmp_rsr = function(inst, addr) {
this.print_inst("CMP (register-shifted register)", inst, addr);
var n = (inst >>> 16) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = this.add_with_carry(this.reg(n), bitops.not(shifted), 1);
this.set_apsr(ret, true);
this.print_inst_rsr(addr, inst, "cmp", null, null, n, m, shift_t, s);
};
ARMv7_CPU.prototype.eor_rsr = function(inst, addr) {
this.print_inst("EOR (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.xor(this.reg(n), shifted);
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, false);
this.print_inst_rsr(addr, inst, "eor", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.mvn_rsr = function(inst, addr) {
this.print_inst("MVN (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.not(shifted);
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, false);
this.print_inst_rsr(addr, inst, "mvn", sf, d, null, m, shift_t, s);
};
ARMv7_CPU.prototype.orr_rsr = function(inst, addr) {
this.print_inst("ORR (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.or(this.reg(n), shifted);
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, false);
this.print_inst_rsr(addr, inst, "orr", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.rsb_rsr = function(inst, addr) {
this.print_inst("RSB (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = this.add_with_carry(bitops.not(this.reg(n)), shifted, 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, true);
}
this.print_inst_rsr(addr, inst, "rsb", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.sbc_rsr = function(inst, addr) {
this.print_inst("SBC (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = this.add_with_carry(this.reg(n), bitops.not(shifted), this.cpsr.c);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, true);
}
this.print_inst_rsr(addr, inst, "sbc", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.sub_rsr = function(inst, addr) {
this.print_inst("SUB (register-shifted register)", inst, addr);
var sf = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var d = (inst >>> 12) & 0xf;
var s = (inst >>> 8) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = this.add_with_carry(this.reg(n), bitops.not(shifted), 1);
if (d == 15) {
this.branch_to = ret;
} else {
this.regs[d] = ret;
if (sf)
this.set_apsr(ret, true);
}
this.print_inst_rsr(addr, inst, "sub", sf, d, n, m, shift_t, s);
};
ARMv7_CPU.prototype.tst_rsr = function(inst, addr) {
this.print_inst("TST (register-shifted register)", inst, addr);
var s = inst & 0x00100000;
var n = (inst >>> 16) & 0xf;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var shift_t = this.decode_reg_shift(type);
var shift_n = bitops.get_bits(this.reg(s), 7, 0);
var shifted = this.shift_c(this.reg(m), shift_t, shift_n, this.cpsr.c);
var ret = bitops.and(this.reg(n), shifted);
this.set_apsr(ret, false);
this.print_inst_rsr(addr, inst, "tst", null, null, n, m, shift_t, s);
};
/*
* Load Store
*/
ARMv7_CPU.prototype.ldrh_imm = function(inst, addr) {
this.print_inst("LDRH (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
// data = MemU[address,2];
var data = this.ld_halfword(address);
if (is_wback)
this.regs[n] = offset_addr;
this.regs[t] = data;
this.log_regs(null);
this.print_inst_imm(addr, inst, "ldrh", null, t, n, imm32, true, is_wback, is_add);
};
ARMv7_CPU.prototype.ldrh_reg = function(inst, addr) {
this.print_inst("LDRH (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.SRType_LSL, 0, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
// data = MemU[address,2];
var data = this.ld_halfword(address);
if (is_wback)
this.regs[n] = offset_addr;
this.regs[t] = data;
this.print_inst_reg(addr, inst, "ldrh", null, t, n, m, this.SRType_LSL, 0, true, is_wback, is_add);
};
ARMv7_CPU.prototype.ldrsb_imm = function(inst, addr) {
this.print_inst("LDRSB (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
this.regs[t] = bitops.sign_extend(this.ld_byte(address), 8, 32);
if (is_wback)
this.regs[n] = offset_addr;
//this.print_inst_reg(addr, inst, "ldrsb", null, t, n, m, null, null, true, is_wback, is_add);
this.print_inst_unimpl(addr, inst, "ldrsb");
};
ARMv7_CPU.prototype.ldrsb_reg = function(inst, addr) {
this.print_inst("LDRSB (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var offset = this.shift(this.reg(m), this.SRType_LSL, 0, this.cpsr.c);
var valn = this.reg(n);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
this.regs[t] = bitops.sign_extend(this.ld_byte(address), 8, 32);
if (is_wback)
this.regs[n] = offset_addr;
//this.print_inst_reg(addr, inst, "ldrsb", null, t, n, m, null, null, true, is_wback, is_add);
this.print_inst_unimpl(addr, inst, "ldrsb");
};
ARMv7_CPU.prototype.str_reg = function(inst, addr) {
this.print_inst("STR (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
this.decode_imm_shift(type, imm5);
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
address = bitops.get_bits64(address, 31, 0); // XXX
var data = this.reg(t);
this.st_word(address, data);
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "str", null, t, n, m, this.shift_t, this.shift_n, true, is_wback);
};
ARMv7_CPU.prototype.strbt_a1 = function(inst, addr) {
this.print_inst("STRBT A1", inst, addr);
var u = inst & (1 << 23);
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm32 = inst & 0xfff;
var is_add = u == 1;
var valn = this.reg(n);
var offset = imm32;
var offset_addr = valn + (is_add ? offset : -offset);
this.st_byte(valn, bitops.get_bits(this.reg(t), 7, 0));
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "strbt", null, t, n, m, this.shift_t, this.shift_n, true, true);
};
ARMv7_CPU.prototype.strbt_a2 = function(inst, addr) {
this.print_inst("STRBT A2", inst, addr);
var u = (inst >>> 23) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var is_add = u == 1;
this.decode_imm_shift(type, imm5);
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
this.st_byte(valn, bitops.get_bits(this.reg(t), 7, 0));
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "strbt", null, t, n, m, this.shift_t, this.shift_n, true, true);
};
ARMv7_CPU.prototype.strb_reg = function(inst, addr) {
this.print_inst("STRB (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm5 = (inst >>> 7) & 0x1f;
var type = (inst >>> 5) & 3;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
this.decode_imm_shift(type, imm5);
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.shift_t, this.shift_n, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
this.st_byte(address, bitops.get_bits(this.reg(t), 7, 0));
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "strb", null, t, n, m, this.shift_t, this.shift_n, true, is_wback);
};
ARMv7_CPU.prototype.strd_reg = function(inst, addr) {
this.print_inst("STRD (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var t2 = t + 1;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var valm = this.reg(m);
var offset_addr = valn + (is_add ? valm : -valm);
var address = is_index ? offset_addr : valn;
this.st_word(address, this.reg(t));
this.st_word(address + 4, this.reg(t2));
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "strd", null, t, n, m, null, null, true, is_wback, is_index);
};
ARMv7_CPU.prototype.strd_imm = function(inst, addr) {
this.print_inst("STRD (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var t2 = t + 1;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
this.st_word(address, this.reg(t));
this.st_word(address + 4, this.reg(t2));
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "strd", null, t, n, imm32, true, is_wback, is_add);
};
ARMv7_CPU.prototype.strh_imm = function(inst, addr) {
this.print_inst("STRH (immediate)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var imm4h = (inst >>> 8) & 0xf;
var imm4l = inst & 0xf;
var imm32 = (imm4h << 4) + imm4l;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset_addr = valn + (is_add ? imm32 : -imm32);
var address = is_index ? offset_addr : valn;
this.st_halfword(address, bitops.get_bits(this.reg(t), 15, 0));
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_imm(addr, inst, "strh", null, t, n, imm32, true, is_wback, is_add);
};
ARMv7_CPU.prototype.strh_reg = function(inst, addr) {
this.print_inst("STRH (register)", inst, addr);
var p = (inst >>> 24) & 1;
var u = (inst >>> 23) & 1;
var w = (inst >>> 21) & 1;
var n = (inst >>> 16) & 0xf;
var t = (inst >>> 12) & 0xf;
var m = inst & 0xf;
var is_index = p == 1;
var is_add = u == 1;
var is_wback = p === 0 || w == 1;
var valn = this.reg(n);
var offset = this.shift(this.reg(m), this.SRType_LSL, 0, this.cpsr.c);
var offset_addr = valn + (is_add ? offset : -offset);
var address = is_index ? offset_addr : valn;
this.st_halfword(address, bitops.get_bits(this.reg(t), 15, 0));
if (is_wback)
this.regs[n] = offset_addr;
this.print_inst_reg(addr, inst, "strh", null, t, n, m, this.SRType_LSL, 0, true, is_wback, is_add);
};
ARMv7_CPU.prototype.ldm = function(inst, addr) {
this.pri
gitextract_vip1hlxs/ ├── .gitmodules ├── Image-3.10.29 ├── README.md ├── arm-js.html ├── css/ │ └── jquery-ui-1.8.18.custom.css ├── initramfs.cpio.lzo ├── js/ │ ├── 9p.js │ ├── JSONlocalStorage.js │ ├── armv7-cp15.js │ ├── armv7-cpu.js │ ├── armv7-mmu.js │ ├── bitops.js │ ├── display.js │ ├── filesystem.js │ ├── jquery-1.7.2.js │ ├── logger.js │ ├── number64.js │ ├── option.js │ ├── parameter.js │ ├── symbols.js │ ├── tracer.js │ ├── utils.js │ ├── vexpress.js │ └── virtio.js ├── misc/ │ ├── busybox-1.20.2.config │ ├── jquery-1.7.2-binary.patch │ ├── linux-3.6.1.config │ ├── simple-http-server.rb │ ├── symbols.rb │ ├── term.js.patch │ └── vexpress-armjs.dts └── vexpress-armjs.dtb
SYMBOL INDEX (94 symbols across 17 files)
FILE: js/9p.js
function Protocol9P2000u (line 11) | function Protocol9P2000u(net9p) {
function Net9p (line 539) | function Net9p(virtio) {
FILE: js/JSONlocalStorage.js
function JSONlocalStorage (line 7) | function JSONlocalStorage(name, target, list) {
FILE: js/armv7-cp15.js
function ARMv7_CP15 (line 10) | function ARMv7_CP15(options, cpu) {
FILE: js/armv7-cpu.js
function ARMv7_CPU (line 7) | function ARMv7_CPU(options, memctlr) {
FILE: js/armv7-mmu.js
function ARMv7_MMU (line 10) | function ARMv7_MMU(cpu, memctlr) {
function toStringPageTable (line 233) | function toStringPageTable(table, addr) {
FILE: js/bitops.js
function assert (line 7) | function assert(cond, val) {
function assert2 (line 18) | function assert2(x, y, str) {
function BitOps (line 28) | function BitOps() {
FILE: js/display.js
function Display (line 7) | function Display(display_id, options) {
FILE: js/filesystem.js
function fsTestAvailability (line 9) | function fsTestAvailability(requestByte, sCallback, eCallback) {
function HTML5FileSystem (line 23) | function HTML5FileSystem(root, requestByte) {
function errorHandler (line 38) | function errorHandler(e) {
function getMetadata (line 194) | function getMetadata(entry) {
FILE: js/jquery-1.7.2.js
function jQuerySub (line 897) | function jQuerySub( selector, context ) {
function doScrollCheck (line 963) | function doScrollCheck() {
function createFlags (line 990) | function createFlags( flags ) {
function resolveFunc (line 1325) | function resolveFunc( i ) {
function progressFunc (line 1333) | function progressFunc( i ) {
function dataAttr (line 1985) | function dataAttr( elem, key, data ) {
function isEmptyDataObject (line 2016) | function isEmptyDataObject( obj ) {
function handleQueueMarkDefer (line 2034) | function handleQueueMarkDefer( elem, type, src ) {
function resolve (line 2193) | function resolve() {
function returnFalse (line 3546) | function returnFalse() {
function returnTrue (line 3549) | function returnTrue() {
function dirNodeCheck (line 5260) | function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function dirCheck (line 5293) | function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
function isDisconnected (line 5566) | function isDisconnected( node ) {
function winnow (line 5683) | function winnow( elements, qualifier, keep ) {
function createSafeFragment (line 5720) | function createSafeFragment( document ) {
function root (line 6092) | function root( elem, cur ) {
function cloneCopyEvent (line 6099) | function cloneCopyEvent( src, dest ) {
function cloneFixAttributes (line 6127) | function cloneFixAttributes( src, dest ) {
function getAll (line 6272) | function getAll( elem ) {
function fixDefaultChecked (line 6285) | function fixDefaultChecked( elem ) {
function findInputs (line 6291) | function findInputs( elem ) {
function shimCloneNode (line 6302) | function shimCloneNode( elem ) {
function getWidthOrHeight (line 6793) | function getWidthOrHeight( elem, name, extra ) {
function addToPrefiltersOrTransports (line 7034) | function addToPrefiltersOrTransports( structure ) {
function inspectPrefiltersOrTransports (line 7070) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
function ajaxExtend (line 7112) | function ajaxExtend( target, src ) {
function done (line 7455) | function done( status, nativeStatusText, responses, headers ) {
function buildParams (line 7778) | function buildParams( prefix, obj, traditional, add ) {
function ajaxHandleResponses (line 7828) | function ajaxHandleResponses( s, jqXHR, responses ) {
function ajaxConvert (line 7893) | function ajaxConvert( s, response ) {
function createStandardXHR (line 8158) | function createStandardXHR() {
function createActiveXHR (line 8164) | function createActiveXHR() {
function doAnimation (line 8503) | function doAnimation() {
function stopQueue (line 8659) | function stopQueue( elem, data, index ) {
function createFxNow (line 8701) | function createFxNow() {
function clearFxNow (line 8706) | function clearFxNow() {
function genFx (line 8711) | function genFx( type, num ) {
function t (line 8826) | function t( gotoEnd ) {
function defaultDisplay (line 9024) | function defaultDisplay( nodeName ) {
function getWindow (line 9308) | function getWindow( elem ) {
FILE: js/logger.js
function Logger (line 7) | function Logger(target, options) {
FILE: js/number64.js
function Number64 (line 7) | function Number64(high, low) {
function assert_equal (line 121) | function assert_equal(sub, obj, message) {
function TestNumber64 (line 129) | function TestNumber64() {
FILE: js/option.js
function Options (line 7) | function Options() {
FILE: js/parameter.js
function Configurations (line 7) | function Configurations() {
function Parameters (line 56) | function Parameters() {
FILE: js/tracer.js
function Tracer (line 7) | function Tracer(target, options) {
function BranchTracer (line 80) | function BranchTracer(target, options) {
FILE: js/utils.js
function assert (line 7) | function assert(cond, val) {
function assert2 (line 18) | function assert2(x, y, str) {
function toStringBinInst (line 28) | function toStringBinInst(inst) {
function toStringBin (line 41) | function toStringBin(val, n) {
function toStringBin32 (line 48) | function toStringBin32(val) {
function toStringBin64 (line 52) | function toStringBin64(val) {
function toStringBin16 (line 56) | function toStringBin16(val) {
function toStringHex32 (line 60) | function toStringHex32(ulong) {
function toStringNum (line 75) | function toStringNum(num) {
function toStringInst (line 79) | function toStringInst(inst) {
function toStringAscii (line 83) | function toStringAscii(uint) {
function abort (line 95) | function abort(str) {
function stringToLong (line 99) | function stringToLong(str) {
function getCurrentTime (line 110) | function getCurrentTime() {
FILE: js/vexpress.js
function Device (line 7) | function Device() {
function SystemRegisters (line 80) | function SystemRegisters(baseaddr, options) {
function UnimplementedDevice (line 156) | function UnimplementedDevice(baseaddr) {
function GenericInterruptController (line 163) | function GenericInterruptController(baseaddr) {
function DualTimer (line 386) | function DualTimer(baseaddr, irq, gic) {
function SystemController (line 569) | function SystemController(baseaddr) {
function SystemIO (line 590) | function SystemIO(options) {
function UART (line 669) | function UART(id, baseaddr, irq, gic) {
function Memory (line 922) | function Memory(size) {
function MemoryController (line 946) | function MemoryController(options, memory, io) {
function System (line 1077) | function System(configs, options) {
function VersatileExpress (line 1485) | function VersatileExpress(configs, options) {
FILE: js/virtio.js
function VirtioMMIO (line 8) | function VirtioMMIO(baseaddr, irq, gic) {
function VirtioVring (line 182) | function VirtioVring(memctlr, mmio) {
function Virtio9P (line 306) | function Virtio9P(memctlr, vring) {
Condensed preview — 32 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,631K chars).
[
{
"path": ".gitmodules",
"chars": 101,
"preview": "[submodule \"js/simpleterm\"]\n\tpath = js/simpleterm\n\turl = https://github.com/michaelko/simpleterm.git\n"
},
{
"path": "README.md",
"chars": 927,
"preview": "Arm-js\n======\n\nArm-js is an ARM emulator written in Javascript. It emulates ARMv7-A\nand some peripherals of Versatile Ex"
},
{
"path": "arm-js.html",
"chars": 14468,
"preview": "<!--\n/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 "
},
{
"path": "css/jquery-ui-1.8.18.custom.css",
"chars": 20231,
"preview": "/*\n * jQuery UI CSS Framework 1.8.18\n *\n * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)\n * Dual licensed unde"
},
{
"path": "js/9p.js",
"chars": 20843,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/JSONlocalStorage.js",
"chars": 1066,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/armv7-cp15.js",
"chars": 21606,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/armv7-cpu.js",
"chars": 202975,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/armv7-mmu.js",
"chars": 11312,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/bitops.js",
"chars": 15851,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/display.js",
"chars": 485,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/filesystem.js",
"chars": 8796,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/jquery-1.7.2.js",
"chars": 253337,
"preview": "/*!\n * jQuery JavaScript Library v1.7.2\n * http://jquery.com/\n *\n * Copyright 2011, John Resig\n * Dual licensed under th"
},
{
"path": "js/logger.js",
"chars": 1171,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/number64.js",
"chars": 9274,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/option.js",
"chars": 7667,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/parameter.js",
"chars": 3867,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/symbols.js",
"chars": 797851,
"preview": "Symbols = Object();\nSymbols[0xc018cdb4] = \"vtconsole_class_init\";\nSymbols[0xc010f8ec] = \"qdisc_rcu_free\";\nSymbols[0xc002"
},
{
"path": "js/tracer.js",
"chars": 4651,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/utils.js",
"chars": 2576,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/vexpress.js",
"chars": 51947,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "js/virtio.js",
"chars": 11907,
"preview": "/*!\n * Javascript ARMv7 Emulator\n *\n * Copyright 2012, Ryota Ozaki\n * Dual licensed under the MIT or GPL Version 2 licen"
},
{
"path": "misc/busybox-1.20.2.config",
"chars": 30767,
"preview": "#\n# Automatically generated make config: don't edit\n# Busybox version: 1.20.2\n# Sun Oct 28 05:09:21 2012\n#\nCONFIG_HAVE_D"
},
{
"path": "misc/jquery-1.7.2-binary.patch",
"chars": 1153,
"preview": "--- jquery-1.7.2.js\t2012-03-22 04:46:56.000000000 +0900\n+++ jquery-1.7.2-binary.js\t2012-06-02 22:02:16.000000000 +0900\n@"
},
{
"path": "misc/linux-3.6.1.config",
"chars": 23573,
"preview": "#\n# Automatically generated file; DO NOT EDIT.\n# Linux/arm 3.6.1 Kernel Configuration\n#\nCONFIG_ARM=y\nCONFIG_SYS_SUPPORTS"
},
{
"path": "misc/simple-http-server.rb",
"chars": 309,
"preview": "require 'webrick'\n\nsrv = WEBrick::HTTPServer.new({:DocumentRoot => '.',\n :BindAddress => '"
},
{
"path": "misc/symbols.rb",
"chars": 694,
"preview": "#!/usr/bin/ruby\n#\n# Javascript ARMv7 Emulator\n#\n# Copyright 2012, Ryota Ozaki\n# Dual licensed under the MIT or GPL Versi"
},
{
"path": "misc/term.js.patch",
"chars": 939,
"preview": "--- /tmp/term.js.beautiful\t2012-09-30 23:18:01.000000000 +0900\n+++ term.js\t2012-09-30 23:28:47.000000000 +0900\n@@ -39,14"
},
{
"path": "misc/vexpress-armjs.dts",
"chars": 4305,
"preview": "/*\n * ARM Ltd. Versatile Express for arm-js\n * Licensed under GPL 2.0\n *\n * This DTS is based on vexpress-v2p-ca9.dts\n *"
}
]
// ... and 3 more files (download for full content)
About this extraction
This page contains the full source code of the ozaki-r/arm-js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 32 files (1.5 MB), approximately 501.9k tokens, and a symbol index with 94 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.