summary refs log blame commit diff stats
path: root/doc/pydoc/ranger.container.keybuffer.html
blob: 4990a3fcd611a831befff37bf8ca672df18a12a3 (plain) (tree)











































































                                                                                                                                                                                                                                                            
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.container.keybuffer</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.container.html"><font color="#ffffff">container</font></a>.keybuffer</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/work/ranger/ranger/container/keybuffer.py">/home/hut/work/ranger/ranger/container/keybuffer.py</a></font></td></tr></table>
    <p></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="builtins.html#object">builtins.object</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.container.keybuffer.html#KeyBuffer">KeyBuffer</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="KeyBuffer">class <strong>KeyBuffer</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="KeyBuffer-__init__"><strong>__init__</strong></a>(self)</dt></dl>

<dl><dt><a name="KeyBuffer-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>returns&nbsp;a&nbsp;concatenation&nbsp;of&nbsp;all&nbsp;characters</tt></dd></dl>

<dl><dt><a name="KeyBuffer-append"><strong>append</strong></a>(self, key)</dt><dd><tt>Append&nbsp;a&nbsp;key&nbsp;to&nbsp;the&nbsp;keybuffer,&nbsp;or&nbsp;initial&nbsp;numbers&nbsp;to<br>
the&nbsp;number&nbsp;attribute.</tt></dd></dl>

<dl><dt><a name="KeyBuffer-clear"><strong>clear</strong></a>(self)</dt><dd><tt>Clear&nbsp;the&nbsp;keybuffer&nbsp;and&nbsp;restore&nbsp;the&nbsp;initial&nbsp;state</tt></dd></dl>

<dl><dt><a name="KeyBuffer-tuple_with_numbers"><strong>tuple_with_numbers</strong></a>(self)</dt><dd><tt>Get&nbsp;a&nbsp;tuple&nbsp;of&nbsp;ascii&nbsp;codes.</tt></dd></dl>

<dl><dt><a name="KeyBuffer-tuple_without_numbers"><strong>tuple_without_numbers</strong></a>(self)</dt><dd><tt>Get&nbsp;a&nbsp;tuple&nbsp;of&nbsp;ascii&nbsp;codes.<br>
If&nbsp;the&nbsp;keybuffer&nbsp;starts&nbsp;with&nbsp;numbers,&nbsp;those&nbsp;will<br>
be&nbsp;left&nbsp;out.&nbsp;To&nbsp;access&nbsp;them,&nbsp;use&nbsp;keybuffer.number</tt></dd></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#eeaa77">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
    
<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt><a name="-to_string"><strong>to_string</strong></a>(i)</dt></dl>
</td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
    
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>NINE</strong> = 57<br>
<strong>ZERO</strong> = 48</td></tr></table>
</body></html>
const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "convert r/m32 to " << Xname[dest] << end(); const int32_t* src = effective_address(modrm); Xmm[dest] = *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: convert floating point to int :(before "End Initialize Op Names") put_new(Name_f3_0f, "2d", "convert floating-point to int (cvtss2si)"); put_new(Name_f3_0f, "2c", "truncate floating-point to int (cvttss2si)"); :(code) void test_cvtss2si() { Xmm[0] = 9.8; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 2d c0 \n" // ModR/M in binary: 11 (direct mode) 000 (EAX) 000 (XMM0) ); CHECK_TRACE_CONTENTS( "run: convert x/m32 to EAX\n" "run: x/m32 is XMM0\n" "run: EAX is now 0x0000000a\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x2d: { // convert float to integer const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "convert x/m32 to " << rname(dest) << end(); const float* src = effective_address_float(modrm); Reg[dest].i = round(*src); trace(Callstack_depth+1, "run") << rname(dest) << " is now 0x" << HEXWORD << Reg[dest].i << end(); break; } :(code) void test_cvttss2si() { Xmm[0] = 9.8; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 2c c0 \n" // ModR/M in binary: 11 (direct mode) 000 (EAX) 000 (XMM0) ); CHECK_TRACE_CONTENTS( "run: truncate x/m32 to EAX\n" "run: x/m32 is XMM0\n" "run: EAX is now 0x00000009\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x2c: { // truncate float to integer const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "truncate x/m32 to " << rname(dest) << end(); const float* src = effective_address_float(modrm); Reg[dest].i = trunc(*src); trace(Callstack_depth+1, "run") << rname(dest) << " is now 0x" << HEXWORD << Reg[dest].i << end(); break; } //:: add :(before "End Initialize Op Names") put_new(Name_f3_0f, "58", "add floats (addss)"); :(code) void test_addss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 58 c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: add x/m32 to XMM0\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 5\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x58: { // add x/m32 to x32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "add x/m32 to " << Xname[dest] << end(); const float* src = effective_address_float(modrm); Xmm[dest] += *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: subtract :(before "End Initialize Op Names") put_new(Name_f3_0f, "5c", "subtract floats (subss)"); :(code) void test_subss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 5c c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: subtract x/m32 from XMM0\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 1\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x5c: { // subtract x/m32 from x32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "subtract x/m32 from " << Xname[dest] << end(); const float* src = effective_address_float(modrm); Xmm[dest] -= *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: multiply :(before "End Initialize Op Names") put_new(Name_f3_0f, "59", "multiply floats (mulss)"); :(code) void test_mulss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 59 c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: multiply XMM0 by x/m32\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 6\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x59: { // multiply x32 by x/m32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "multiply " << Xname[dest] << " by x/m32" << end(); const float* src = effective_address_float(modrm); Xmm[dest] *= *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: divide :(before "End Initialize Op Names") put_new(Name_f3_0f, "5e", "divide floats (divss)"); :(code) void test_divss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 5e c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: divide XMM0 by x/m32\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 1.5\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x5e: { // divide x32 by x/m32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "divide " << Xname[dest] << " by x/m32" << end(); const float* src = effective_address_float(modrm); Xmm[dest] /= *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: min :(before "End Initialize Op Names") put_new(Name_f3_0f, "5d", "minimum of two floats (minss)"); :(code) void test_minss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 5d c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: minimum of XMM0 and x/m32\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 2\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x5d: { // minimum of x32, x/m32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "minimum of " << Xname[dest] << " and x/m32" << end(); const float* src = effective_address_float(modrm); Xmm[dest] = min(Xmm[dest], *src); trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: max :(before "End Initialize Op Names") put_new(Name_f3_0f, "5f", "maximum of two floats (maxss)"); :(code) void test_maxss() { Xmm[0] = 3.0; Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 5f c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: maximum of XMM0 and x/m32\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 3\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x5f: { // maximum of x32, x/m32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "maximum of " << Xname[dest] << " and x/m32" << end(); const float* src = effective_address_float(modrm); Xmm[dest] = max(Xmm[dest], *src); trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: reciprocal :(before "End Initialize Op Names") put_new(Name_f3_0f, "53", "reciprocal of float (rcpss)"); :(code) void test_rcpss() { Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 53 c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: reciprocal of x/m32 into XMM0\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 0.5\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x53: { // reciprocal of x/m32 into x32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "reciprocal of x/m32 into " << Xname[dest] << end(); const float* src = effective_address_float(modrm); Xmm[dest] = 1.0 / *src; trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } //:: square root :(before "End Initialize Op Names") put_new(Name_f3_0f, "51", "square root of float (sqrtss)"); :(code) void test_sqrtss() { Xmm[1] = 2.0; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 51 c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: square root of x/m32 into XMM0\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 1.41421\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x51: { // square root of x/m32 into x32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "square root of x/m32 into " << Xname[dest] << end(); const float* src = effective_address_float(modrm); Xmm[dest] = sqrt(*src); trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } :(before "End Includes") #include <math.h> //:: inverse square root :(before "End Initialize Op Names") put_new(Name_f3_0f, "52", "inverse square root of float (rsqrtss)"); :(code) void test_rsqrtss() { Xmm[1] = 0.01; run( "== code 0x1\n" // op ModR/M SIB displacement immediate "f3 0f 52 c1 \n" // ModR/M in binary: 11 (direct mode) 000 (XMM0) 001 (XMM1) ); CHECK_TRACE_CONTENTS( "run: inverse square root of x/m32 into XMM0\n" "run: x/m32 is XMM1\n" "run: XMM0 is now 10\n" ); } :(before "End Three-Byte Opcodes Starting With f3 0f") case 0x52: { // inverse square root of x/m32 into x32 const uint8_t modrm = next(); const uint8_t dest = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "inverse square root of x/m32 into " << Xname[dest] << end(); const float* src = effective_address_float(modrm); Xmm[dest] = 1.0 / sqrt(*src); trace(Callstack_depth+1, "run") << Xname[dest] << " is now " << Xmm[dest] << end(); break; } :(code) float* effective_address_float(uint8_t modrm) { const uint8_t mod = (modrm>>6); // ignore middle 3 'reg opcode' bits const uint8_t rm = modrm & 0x7; if (mod == 3) { // mod 3 is just register direct addressing trace(Callstack_depth+1, "run") << "x/m32 is " << Xname[rm] << end(); return &Xmm[rm]; } uint32_t addr = effective_address_number(modrm); trace(Callstack_depth+1, "run") << "effective address contains " << read_mem_f32(addr) << end(); return mem_addr_f32(addr); } //: compare :(before "End Initialize Op Names") put_new(Name_0f, "2f", "compare: set CF if x32 < xm32 (comiss)"); :(code) void test_compare_x32_with_mem_at_rm32() { Reg[EAX].i = 0x2000; Xmm[3] = 0.5; run( "== code 0x1\n" // op ModR/M SIB displacement immediate " 0f 2f 18 \n" // compare XMM3 with *EAX // ModR/M in binary: 00 (indirect mode) 011 (lhs XMM3) 000 (rhs EAX) "== data 0x2000\n" "00 00 00 00\n" // 0x00000000 = 0.0 ); CHECK_TRACE_CONTENTS( "run: compare XMM3 with x/m32\n" "run: effective address is 0x00002000 (EAX)\n" "run: SF=0; ZF=0; CF=0; OF=0\n" ); } :(before "End Two-Byte Opcodes Starting With 0f") case 0x2f: { // set CF if x32 < x/m32 const uint8_t modrm = next(); const uint8_t reg1 = (modrm>>3)&0x7; trace(Callstack_depth+1, "run") << "compare " << Xname[reg1] << " with x/m32" << end(); const float* arg2 = effective_address_float(modrm); // Flag settings carefully copied from the Intel manual. // See also https://stackoverflow.com/questions/7057501/x86-assembler-floating-point-compare/7057771#7057771 SF = ZF = CF = OF = false; if (Xmm[reg1] == *arg2) ZF = true; if (Xmm[reg1] < *arg2) CF = true; trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; CF=" << CF << "; OF=" << OF << end(); break; }