Author |
Message
|
Admin Site Admin
(send private message)
Posts: 933 Topics: 55
Location: OverHertz Studio | [1711] Sample log2i - posted: 2015-02-15 16:30:10 Decided to write a log2 integer based function written in Zir using a lookup table.
Code:program PE32_CUI 'Sample';
#include 'platform_def.zir';
#include 'console.zir';
byte log2i_table[32] = [
0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7,
19, 27, 23, 6, 26, 5, 4, 31
];
function log2i(int32 value) {
ecx = value;
eax = ecx;
eax >> 1; ecx |= eax; eax = ecx;
eax >> 2; ecx |= eax; eax = ecx;
eax >> 4; ecx |= eax; eax = ecx;
eax >> 8; ecx |= eax; eax = ecx;
eax >> 16; ecx |= eax;
eax = 0x07C4ACDD; imul ecx; eax >> 27;
eax = log2i_table[eax];
}
edi = log2i(4096);
println(edi);
wait_key();
ExitProcess(0);
Please note this is not efficient, it is to show using a table and indexing to avoid branching - see 0CodErr' BSR log2i for better method
Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message. |
0CodErr Ziron Guru (send private message)
Posts: 199 Topics: 37
Location:
| [1712] - posted: 2015-02-15 17:05:43 Maybe I do not understand some actions in your code such as:
Code: eax >> 1; ecx |= eax; eax = ecx;
eax >> 2; ecx |= eax; eax = ecx;
eax >> 4; ecx |= eax; eax = ecx;
eax >> 8; ecx |= eax; eax = ecx;
eax >> 16; ecx |= eax;
eax = 0x07C4ACDD; imul ecx; eax >> 27;
But integer logarithm can be calculated by using 'bsr' instruction. I wrote an example for compare:
Code:program PE32_CUI 'Sample';
#include 'platform_def.zir';
#include 'console.zir';
byte log2i_table[32] = [
0, 9, 1, 10, 13, 21, 2, 29,
11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7,
19, 27, 23, 6, 26, 5, 4, 31
];
function log2i(int32 value) {
ecx = value;
eax = ecx;
eax >> 1; ecx |= eax; eax = ecx;
eax >> 2; ecx |= eax; eax = ecx;
eax >> 4; ecx |= eax; eax = ecx;
eax >> 8; ecx |= eax; eax = ecx;
eax >> 16; ecx |= eax;
eax = 0x07C4ACDD; imul ecx; eax >> 27;
eax = log2i_table[eax];
}
inline function BSR_log2i($value) {eax = $value; bsr eax, eax; $return eax;}
println(NEW_LINE, 'log2i:', NEW_LINE);
edi = log2i(0x00000001); println(edi);
edi = log2i(0x00000002); println(edi);
edi = log2i(0x00000004); println(edi);
edi = log2i(0x00000008); println(edi);
edi = log2i(0x00000010); println(edi);
edi = log2i(0x00000020); println(edi);
edi = log2i(0x00000040); println(edi);
edi = log2i(0x00000080); println(edi);
edi = log2i(0x00000100); println(edi);
edi = log2i(0x00000200); println(edi);
edi = log2i(0x00000400); println(edi);
edi = log2i(0x00000800); println(edi);
edi = log2i(0x00001000); println(edi);
edi = log2i(0x00002000); println(edi);
edi = log2i(0x00004000); println(edi);
edi = log2i(0x00008000); println(edi);
edi = log2i(0x00010000); println(edi);
edi = log2i(0x00020000); println(edi);
edi = log2i(0x00040000); println(edi);
edi = log2i(0x00080000); println(edi);
edi = log2i(0x00100000); println(edi);
edi = log2i(0x00200000); println(edi);
edi = log2i(0x00400000); println(edi);
edi = log2i(0x00800000); println(edi);
edi = log2i(0x01000000); println(edi);
edi = log2i(0x02000000); println(edi);
edi = log2i(0x04000000); println(edi);
edi = log2i(0x08000000); println(edi);
edi = log2i(0x10000000); println(edi);
edi = log2i(0x20000000); println(edi);
edi = log2i(0x40000000); println(edi);
edi = log2i(0x80000000); println(edi);
println(NEW_LINE, 'BSR_log2i:', NEW_LINE);
edi = BSR_log2i(0x00000001); println(edi);
edi = BSR_log2i(0x00000002); println(edi);
edi = BSR_log2i(0x00000004); println(edi);
edi = BSR_log2i(0x00000008); println(edi);
edi = BSR_log2i(0x00000010); println(edi);
edi = BSR_log2i(0x00000020); println(edi);
edi = BSR_log2i(0x00000040); println(edi);
edi = BSR_log2i(0x00000080); println(edi);
edi = BSR_log2i(0x00000100); println(edi);
edi = BSR_log2i(0x00000200); println(edi);
edi = BSR_log2i(0x00000400); println(edi);
edi = BSR_log2i(0x00000800); println(edi);
edi = BSR_log2i(0x00001000); println(edi);
edi = BSR_log2i(0x00002000); println(edi);
edi = BSR_log2i(0x00004000); println(edi);
edi = BSR_log2i(0x00008000); println(edi);
edi = BSR_log2i(0x00010000); println(edi);
edi = BSR_log2i(0x00020000); println(edi);
edi = BSR_log2i(0x00040000); println(edi);
edi = BSR_log2i(0x00080000); println(edi);
edi = BSR_log2i(0x00100000); println(edi);
edi = BSR_log2i(0x00200000); println(edi);
edi = BSR_log2i(0x00400000); println(edi);
edi = BSR_log2i(0x00800000); println(edi);
edi = BSR_log2i(0x01000000); println(edi);
edi = BSR_log2i(0x02000000); println(edi);
edi = BSR_log2i(0x04000000); println(edi);
edi = BSR_log2i(0x08000000); println(edi);
edi = BSR_log2i(0x10000000); println(edi);
edi = BSR_log2i(0x20000000); println(edi);
edi = BSR_log2i(0x40000000); println(edi);
edi = BSR_log2i(0x80000000); println(edi);
wait_key();
ExitProcess(0);
|
Admin Site Admin
(send private message)
Posts: 933 Topics: 55
Location: OverHertz Studio | [1713] - posted: 2015-02-15 17:27:32 The idea of my sample is more of using table as sample, but using BSR, i never thought about that, it is sure to be 1000% faster of course, thanks
Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message. |
0CodErr Ziron Guru (send private message)
Posts: 199 Topics: 37
Location:
| [1726] - posted: 2015-02-18 13:19:12
“ | The idea of my sample is more of using table as sample |
For this purpose i suggest example which translate file size in bytes to human readable format, it also uses $log2i:
Code:program PE32_CUI 'readable_f_size';
#include 'platform_def.zir';
#include 'console.zir';
#include 'zirutils.zir';
#include 'strutils.zir';
byte units[] = [
0x62, 0x00, 0x00, 0x00, // byte // b
0x6B, 0x62, 0x00, 0x00, // kilobyte // kb
0x4D, 0x62, 0x00, 0x00, // Megabyte // Mb
0x47, 0x62, 0x00, 0x00 // Gigabyte // Gb
];
function ReadableFileSize(dword bytes; char* buffer) {
uses ebx;
eax = bytes; ecx = 0;
while (eax => 1024) {eax += 512; ecx++; eax >> $log2i(1024);}
ebx = @[ecx*4 + @units];
dw2str(eax, buffer);
strAppend(buffer, ebx, -1);
return buffer;
}
char buf[32];
inline procedure Test($bytes) {
eax = ReadableFileSize($bytes, @buf); println([char*]eax);
}
test(0);
test(500);
test(1000);
test(1023);
test(1024);
test(1025);
test(2000);
test(2000000);
test(1000000000);
test(1073741824);
test(2051234567);
wait_key();
ExitProcess(0);
Of course it can has more readable code when you fix some bugs |
0CodErr Ziron Guru (send private message)
Posts: 199 Topics: 37
Location:
| [1727] - posted: 2015-02-18 13:24:24 Also someone can want to get 64-bit file size in 32 bit mode.
Code:program PE32_CUI 'readable_f_size';
#include 'platform_def.zir';
#include 'console.zir';
#include 'zirutils.zir';
#include 'strutils.zir';
byte units[] = [
0x62, 0x00, 0x00, 0x00, // byte // b
0x6B, 0x62, 0x00, 0x00, // kilobyte // kb
0x4D, 0x62, 0x00, 0x00, // Megabyte // Mb
0x47, 0x62, 0x00, 0x00, // Gigabyte // Gb
0x54, 0x62, 0x00, 0x00, // Terabyte // Tb
0x50, 0x62, 0x00, 0x00, // Petabyte // Pb
0x45, 0x62, 0x00, 0x00 // Exabyte // Eb
];
// this function returns valid values for
// sizes from 0 to 0xFFFFFFFFFFFFFDFF bytes (16 Exabytes - 512 bytes)
//
// eax += 512; adc edx, 0; << need to avoid
// rounding errors i.e. if 1700 bytes then
// return 2 kb(1.66 round to 2)
function ReadableFileSize64(dword bytesLo, bytesHi; char* buffer) {
uses ebx;
eax = bytesLo; edx = bytesHi; ecx = 0;
while ((eax => 1024) OR (edx <> 0)) {
eax += 512; adc edx, 0;
shrd eax, edx, $log2i(1024);
shr edx, $log2i(1024);
ecx++;
}
ebx = @[ecx*4 + @units];
dw2str(eax, buffer);
strAppend(buffer, ebx, -1);
return buffer;
}
char buf[32];
inline procedure Test($bytesHi, $bytesLo) {
eax = ReadableFileSize64($bytesLo, $bytesHi, @buf);
println([char*]eax);
}
// (hi_dword, lo_dword) // low and hi parts of qword filesize
test(0, 0);
test(0, 500);
test(0, 1000);
test(0, 1023);
test(0, 1024);
test(0, 1025);
test(0, 2000);
test(0, 2000000);
test(0, 1000000000);
test(0, 1073741824);
test(0, 2051234567);
test(0x1, 0xC0000000);
test(0x30FF, 0xFFFFFFE8);
test(0xD0000000, 0x00000000);
test(0xFFFFFFFF, 0xFFFFFDFF);
wait_key();
ExitProcess(0);
It also can be more readable when you fix some bugs(also bug with qword) |
Admin Site Admin
(send private message)
Posts: 933 Topics: 55
Location: OverHertz Studio | [1728] - posted: 2015-02-18 14:01:36 Nice idea, maybe I can add your functions to the new RTL units (hopefully ready in a couple more releases time)
Hopefully today I will get around to fixing all reported issues
Download Ziron
Get free hosting for Ziron related fan-sites and Ziron projects, contact me in private message. |