Index: .bzrignore
===================================================================
--- .bzrignore	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ .bzrignore	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -20,4 +20,7 @@
 kernel/arch/amd64/include/arch/common.h
 kernel/generic/src/debug/real_map.bin
+uspace/app/barber/barber
+uspace/app/barber/images.c
+uspace/app/barber/images.h
 uspace/app/bdsh/bdsh
 uspace/app/bdsh/test-bdsh
@@ -25,4 +28,5 @@
 uspace/app/blkdump/blkdump
 uspace/app/bnchmark/bnchmark
+uspace/drv/char/pl050/pl050
 uspace/app/date/date
 uspace/app/devctl/devctl
@@ -44,4 +48,5 @@
 uspace/app/mkfat/mkfat
 uspace/app/mkmfs/mkmfs
+uspace/app/modplay/modplay
 uspace/app/netecho/netecho
 uspace/app/nettest1/nettest1
@@ -52,4 +57,6 @@
 uspace/app/ping/ping
 uspace/app/ping6/ping6
+uspace/app/rcubench/rcubench
+uspace/app/rcutest/rcutest
 uspace/app/redir/redir
 uspace/app/sbi/sbi
@@ -73,4 +80,5 @@
 uspace/app/wavplay/wavplay
 uspace/app/websrv/websrv
+uspace/dist/app/barber
 uspace/dist/app/bdsh
 uspace/dist/app/bithenge
@@ -95,4 +103,5 @@
 uspace/dist/app/mkfat
 uspace/dist/app/mkmfs
+uspace/dist/app/modplay
 uspace/dist/app/netecho
 uspace/dist/app/nettest1
@@ -103,4 +112,6 @@
 uspace/dist/app/ping
 uspace/dist/app/ping6
+uspace/dist/app/rcubench
+uspace/dist/app/rcutest
 uspace/dist/app/redir
 uspace/dist/app/sbi
@@ -134,4 +145,5 @@
 uspace/dist/drv/ns8250/
 uspace/dist/drv/ohci/
+uspace/dist/drv/pc/
 uspace/dist/drv/pciintel/
 uspace/dist/drv/ps2mouse/
@@ -209,4 +221,6 @@
 uspace/drv/root/root/root
 uspace/drv/root/virt/virt
+uspace/drv/platform/icp/icp
+uspace/drv/platform/pc/pc
 uspace/drv/platform/rootpc/rootpc
 uspace/drv/nic/e1k/e1k
Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ HelenOS.config	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -299,29 +299,29 @@
 % Compiler
 @ "gcc_cross" GNU C Compiler (cross-compiler)
-@ "gcc_native" GNU C Compiler (native)
+@ "clang" Clang
 @ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
 @ "icc" Intel C Compiler
-@ "clang" Clang
+@ "gcc_native" GNU C Compiler (native)
 ! [PLATFORM=amd64|PLATFORM=ia32] COMPILER (choice)
 
 % Compiler
 @ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
+@ "icc" Intel C Compiler
 @ "gcc_native" GNU C Compiler (native)
-@ "icc" Intel C Compiler
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
 ! [PLATFORM=ia64] COMPILER (choice)
 
 % Compiler
 @ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
 @ "gcc_native" GNU C Compiler (native)
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-! [PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice)
+! [PLATFORM=sparc32] COMPILER (choice)
 
 % Compiler
 @ "gcc_cross" GNU C Compiler (cross-compiler)
+@ "clang" Clang
+@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
 @ "gcc_native" GNU C Compiler (native)
-@ "gcc_helenos" GNU C Compiler (experimental HelenOS-specific cross-compiler)
-@ "clang" Clang
-! [PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=sparc32|PLATFORM=sparc64] COMPILER (choice)
+! [PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=abs32le|PLATFORM=arm32|PLATFORM=sparc64] COMPILER (choice)
 
 
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ boot/arch/mips32/Makefile.inc	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -64,4 +64,10 @@
 endif
 
+ifeq ($(MACHINE),msim)
+	RD_DRVS_ESSENTIAL += \
+		platform/msim \
+		block/ddisk
+endif
+
 SOURCES = \
 	arch/$(BARCH)/src/asm.S \
Index: contrib/conf/msim.conf
===================================================================
--- contrib/conf/msim.conf	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ contrib/conf/msim.conf	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -17,2 +17,6 @@
 add dkeyboard keyboard 0x10000000 2
 add dorder order 0x10000100 5
+
+add ddisk disk 0x10000200 6
+disk fmap "hdisk.img"
+
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -105,8 +105,7 @@
 CLANG_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
 	-ffreestanding -fno-builtin -nostdlib -nostdinc \
-	-Wall -Werror -Wextra -Wno-unused-parameter -Wmissing-prototypes \
+	-std=gnu99 -Wall -Werror -Wextra -Wno-unused-parameter -Wmissing-prototypes \
 	-Werror-implicit-function-declaration -Wwrite-strings \
-	-integrated-as \
-	-pipe -target $(CLANG_TARGET)
+	-integrated-as -pipe -target $(CLANG_TARGET)
 
 ifeq ($(CONFIG_DEBUG),y)
Index: kernel/arch/amd64/Makefile.inc
===================================================================
--- kernel/arch/amd64/Makefile.inc	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/arch/amd64/Makefile.inc	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -91,3 +91,2 @@
 	arch/$(KARCH)/include/arch/istate_struct.ag \
 	arch/$(KARCH)/include/arch/context_struct.ag
-
Index: kernel/arch/mips32/include/arch/drivers/msim.h
===================================================================
--- kernel/arch/mips32/include/arch/drivers/msim.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/arch/mips32/include/arch/drivers/msim.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -39,5 +39,7 @@
 #define MSIM_VIDEORAM     0x90000000
 #define MSIM_KBD_ADDRESS  0x90000000
+
 #define MSIM_KBD_IRQ      2
+#define MSIM_DDISK_IRQ    6
 
 #endif
Index: kernel/arch/mips32/src/mach/msim/msim.c
===================================================================
--- kernel/arch/mips32/src/mach/msim/msim.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/arch/mips32/src/mach/msim/msim.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -62,4 +62,5 @@
 void msim_init(void)
 {
+	cp0_unmask_int(MSIM_DDISK_IRQ);
 }
 
Index: kernel/generic/include/typedefs.h
===================================================================
--- kernel/generic/include/typedefs.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/generic/include/typedefs.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -47,14 +47,4 @@
 
 typedef struct {
-	uint64_t lo;
-	int64_t hi;
-} __attribute__ ((aligned(16))) int128_t;
-
-typedef struct {
-	uint64_t lo;
-	uint64_t hi;
-} __attribute__ ((aligned(16))) uint128_t;
-
-typedef struct {
 	volatile atomic_count_t count;
 } atomic_t;
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/generic/src/mm/frame.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -73,23 +73,4 @@
 static size_t mem_avail_req = 0;  /**< Number of frames requested. */
 static size_t mem_avail_gen = 0;  /**< Generation counter. */
-
-/********************/
-/* Helper functions */
-/********************/
-
-NO_TRACE static inline size_t frame_index(zone_t *zone, frame_t *frame)
-{
-	return (size_t) (frame - zone->frames);
-}
-
-NO_TRACE static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
-{
-	return (size_t) (frame - zone->frames) + zone->base;
-}
-
-NO_TRACE static inline bool frame_index_valid(zone_t *zone, size_t index)
-{
-	return (index < zone->count);
-}
 
 /** Initialize frame structure.
Index: kernel/test/smpcall/smpcall1.c
===================================================================
--- kernel/test/smpcall/smpcall1.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/test/smpcall/smpcall1.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2012 Adam Hraska 
+ * Copyright (c) 2012 Adam Hraska
  * All rights reserved.
  *
Index: kernel/test/synch/rcu1.c
===================================================================
--- kernel/test/synch/rcu1.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/test/synch/rcu1.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -698,5 +698,5 @@
 		return true;
 	} else {
-		TPRINTF(err);
+		TPRINTF("%s", err);
 		/* Leak a bit of mem. */
 		return false;
Index: kernel/test/synch/workqueue2.c
===================================================================
--- kernel/test/synch/workqueue2.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ kernel/test/synch/workqueue2.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -129,5 +129,5 @@
 	res = test_custom_workq();
 	if (res) {
-		TPRINTF(res);
+		TPRINTF("%s", res);
 		err = res;
 	}
@@ -135,5 +135,5 @@
 	res = test_custom_workq_stop();
 	if (res) {
-		TPRINTF(res);
+		TPRINTF("%s", res);
 		err = res;
 	}
@@ -141,5 +141,5 @@
 	res = test_workqueue3();
 	if (res) {
-		TPRINTF(res);
+		TPRINTF("%s", res);
 		err = res;
 	}
Index: tools/autogen.py
===================================================================
--- tools/autogen.py	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ tools/autogen.py	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -66,12 +66,12 @@
 	for i in range(len(struct['members'])):
 		member = struct['members'][i]
-		code = code + ("\temit_constant(%s_OFFSET_%s, offsetof(%s_t, %s));\n" % 
+		code = code + ("\temit_constant(%s_OFFSET_%s, offsetof(%s_t, %s));\n" %
 		    (struct['name'].upper(), member['name'].upper(), struct['name'],
 		    member['name']))
-		code = code + ("\temit_constant(%s_SIZE_%s, sizeof(((%s_t *) 0)->%s));\n" % 
+		code = code + ("\temit_constant(%s_SIZE_%s, sizeof(((%s_t *) 0)->%s));\n" %
 		    (struct['name'].upper(), member['name'].upper(), struct['name'],
 		    member['name']))
 		if 'elements' in member.keys():
-			code = code + ("\temit_constant(%s_%s_ITEM_SIZE, sizeof(%s));\n" % 
+			code = code + ("\temit_constant(%s_%s_ITEM_SIZE, sizeof(%s));\n" %
 			    (struct['name'].upper(), member['name'].upper(), member['type']))
 			
@@ -83,5 +83,5 @@
 
 	code = """
-%s		
+%s
 
 #define str(s) #s
@@ -92,5 +92,7 @@
 %s
 
-int main()
+extern int main(int, char *[]);
+
+int main(int argc, char *argv[])
 {
 %s
@@ -100,5 +102,5 @@
 	""" % (generate_includes(struct), generate_struct(struct),
 	    generate_probes(struct), name.upper(), typename)
-
+	
 	return code
 
@@ -167,3 +169,2 @@
 
 run()
-
Index: tools/autotool.py
===================================================================
--- tools/autotool.py	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ tools/autotool.py	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -48,4 +48,7 @@
 PROBE_OUTPUT = 'probe.s'
 
+PROBE_INT128_SOURCE = 'probe_int128.c'
+PROBE_INT128_OUTPUT = 'probe_int128.s'
+
 PACKAGE_BINUTILS = "usually part of binutils"
 PACKAGE_GCC = "preferably version 4.7.0 or newer"
@@ -85,4 +88,6 @@
 	AUTOTOOL_DECLARE("floatsize", "", tag, #type, "", "", sizeof(type));
 
+extern int main(int, char *[]);
+
 int main(int argc, char *argv[])
 {
@@ -101,4 +106,24 @@
 """
 
+PROBE_INT128_HEAD = """#define AUTOTOOL_DECLARE(category, subcategory, tag, name, strc, conc, value) \\
+	asm volatile ( \\
+		"AUTOTOOL_DECLARE\\t" category "\\t" subcategory "\\t" tag "\\t" name "\\t" strc "\\t" conc "\\t%[val]\\n" \\
+		: \\
+		: [val] "n" (value) \\
+	)
+
+#define DECLARE_INTSIZE(tag, type) \\
+	AUTOTOOL_DECLARE("intsize", "unsigned", tag, #type, "", "", sizeof(unsigned type)); \\
+	AUTOTOOL_DECLARE("intsize", "signed", tag, #type, "", "", sizeof(signed type));
+
+extern int main(int, char *[]);
+
+int main(int argc, char *argv[])
+{
+"""
+
+PROBE_INT128_TAIL = """}
+"""
+
 def read_config(fname, config):
 	"Read HelenOS build configuration"
@@ -195,22 +220,22 @@
 		if (config['CROSS_TARGET'] == "arm32"):
 			gnu_target = "arm-linux-gnueabi"
-			clang_target = "arm-unknown-linux"
+			clang_target = "arm-unknown-none"
 			helenos_target = "arm-helenos-gnueabi"
 		
 		if (config['CROSS_TARGET'] == "ia32"):
 			gnu_target = "i686-pc-linux-gnu"
-			clang_target = "i386-unknown-linux"
+			clang_target = "i686-unknown-none"
 			helenos_target = "i686-pc-helenos"
 		
 		if (config['CROSS_TARGET'] == "mips32"):
+			cc_args.append("-mabi=32")
 			gnu_target = "mipsel-linux-gnu"
-			clang_target = "mipsel-unknown-linux"
+			clang_target = "mipsel-unknown-none"
 			helenos_target = "mipsel-helenos"
-			common['CC_ARGS'].append("-mabi=32")
 	
 	if (config['PLATFORM'] == "amd64"):
 		target = config['PLATFORM']
 		gnu_target = "amd64-linux-gnu"
-		clang_target = "x86_64-unknown-linux"
+		clang_target = "x86_64-unknown-none"
 		helenos_target = "amd64-helenos"
 	
@@ -218,5 +243,5 @@
 		target = config['PLATFORM']
 		gnu_target = "arm-linux-gnueabi"
-		clang_target = "arm-unknown-linux"
+		clang_target = "arm-unknown-none-eabi"
 		helenos_target = "arm-helenos-gnueabi"
 	
@@ -224,5 +249,5 @@
 		target = config['PLATFORM']
 		gnu_target = "i686-pc-linux-gnu"
-		clang_target = "i386-unknown-linux"
+		clang_target = "i686-unknown-none"
 		helenos_target = "i686-pc-helenos"
 	
@@ -239,5 +264,5 @@
 			target = config['PLATFORM']
 			gnu_target = "mipsel-linux-gnu"
-			clang_target = "mipsel-unknown-linux"
+			clang_target = "mipsel-unknown-none"
 			helenos_target = "mipsel-helenos"
 		
@@ -245,5 +270,5 @@
 			target = "mips32eb"
 			gnu_target = "mips-linux-gnu"
-			clang_target = "mips-unknown-linux"
+			clang_target = "mips-unknown-none"
 			helenos_target = "mips-helenos"
 	
@@ -255,5 +280,5 @@
 			target = config['PLATFORM']
 			gnu_target = "mips64el-linux-gnu"
-			clang_target = "mips64el-unknown-linux"
+			clang_target = "mips64el-unknown-none"
 			helenos_target = "mips64el-helenos"
 	
@@ -261,5 +286,5 @@
 		target = config['PLATFORM']
 		gnu_target = "ppc-linux-gnu"
-		clang_target = "powerpc-unknown-linux"
+		clang_target = "ppc-unknown-none"
 		helenos_target = "ppc-helenos"
 	
@@ -272,5 +297,5 @@
 		target = config['PLATFORM']
 		gnu_target = "sparc64-linux-gnu"
-		clang_target = "sparc-unknown-linux"
+		clang_target = "sparc-unknown-none"
 		helenos_target = "sparc64-helenos"
 	
@@ -396,5 +421,5 @@
 	
 	for typedef in floatsizes:
-		outf.write("\nDECLARE_FLOATSIZE(\"%s\", %s);\n" % (typedef['tag'], typedef['type']))
+		outf.write("\tDECLARE_FLOATSIZE(\"%s\", %s);\n" % (typedef['tag'], typedef['type']))
 	
 	outf.write(PROBE_TAIL)
@@ -510,4 +535,70 @@
 	return {'unsigned_sizes': unsigned_sizes, 'signed_sizes': signed_sizes, 'unsigned_tags': unsigned_tags, 'signed_tags': signed_tags, 'unsigned_strcs': unsigned_strcs, 'signed_strcs': signed_strcs, 'unsigned_concs': unsigned_concs, 'signed_concs': signed_concs, 'float_tags': float_tags, 'builtin_sizes': builtin_sizes, 'builtin_signs': builtin_signs}
 
+def probe_int128(common):
+	"Generate, compile and parse probing source for 128-bit integers"
+	
+	check_common(common, "CC")
+	
+	outf = open(PROBE_INT128_SOURCE, 'w')
+	outf.write(PROBE_INT128_HEAD)
+	outf.write("\tDECLARE_INTSIZE(\"INT128\", int __attribute((mode(TI))));\n")
+	outf.write(PROBE_INT128_TAIL)
+	outf.close()
+	
+	args = [common['CC']]
+	args.extend(common['CC_ARGS'])
+	args.extend(["-S", "-o", PROBE_INT128_OUTPUT, PROBE_INT128_SOURCE])
+	
+	try:
+		sys.stderr.write("Checking whether the compiler has intrinsic support for 128-bit integers ... ")
+		output = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()
+	except:
+		sys.stderr.write("no\n")
+		return False
+	
+	if (not os.path.isfile(PROBE_INT128_OUTPUT)):
+		sys.stderr.write("no\n")
+		return False
+	
+	inf = open(PROBE_INT128_OUTPUT, 'r')
+	lines = inf.readlines()
+	inf.close()
+	
+	for j in range(len(lines)):
+		tokens = lines[j].strip().split("\t")
+		
+		if (len(tokens) > 0):
+			if (tokens[0] == "AUTOTOOL_DECLARE"):
+				if (len(tokens) < 7):
+					print_error(["Malformed declaration in \"%s\" on line %s." % (PROBE_INT128_OUTPUT, j), COMPILER_FAIL])
+				
+				category = tokens[1]
+				subcategory = tokens[2]
+				tag = tokens[3]
+				name = tokens[4]
+				strc = tokens[5]
+				conc = tokens[6]
+				value = tokens[7]
+				
+				if (category == "intsize"):
+					try:
+						value_int = decode_value(value)
+					except:
+						print_error(["Integer value expected in \"%s\" on line %s." % (PROBE_INT128_OUTPUT, j), COMPILER_FAIL])
+					
+					if (subcategory == "unsigned"):
+						if (value_int != 16):
+							sys.stderr.write("no\n")
+							return False
+					elif (subcategory == "signed"):
+						if (value_int != 16):
+							sys.stderr.write("no\n")
+							return False
+					else:
+						print_error(["Unexpected keyword \"%s\" in \"%s\" on line %s." % (subcategory, PROBE_INT128_OUTPUT, j), COMPILER_FAIL])
+	
+	sys.stderr.write("yes\n")
+	return True
+
 def detect_sizes(probe, bytes, inttags, floattags):
 	"Detect correct types for fixed-size types"
@@ -683,5 +774,5 @@
 	outmk.close()
 
-def create_header(hdname, maps):
+def create_header(hdname, maps, int128):
 	"Create header output"
 	
@@ -703,4 +794,8 @@
 	for typedef in maps['typedefs']:
 		outhd.write('typedef %s %s;\n' % (typedef['oldtype'], typedef['newtype']))
+	
+	if (int128):
+		outhd.write('typedef unsigned int __attribute((mode(TI))) uint128_t;\n')
+		outhd.write('typedef signed int __attribute((mode(TI))) int128_t;\n')
 	
 	outhd.write('\n#endif\n')
@@ -798,8 +893,9 @@
 		
 		if (config['COMPILER'] == "icc"):
-			common['CC'] = "icc"
 			check_app([common['CC'], "-V"], "Intel C++ Compiler", "support is experimental")
 			check_gcc(None, "", common, PACKAGE_GCC)
 			check_binutils(None, binutils_prefix, common, PACKAGE_BINUTILS)
+			
+			common['CC'] = "icc"
 		
 		if (config['COMPILER'] == "clang"):
@@ -845,4 +941,6 @@
 		)
 		
+		int128 = probe_int128(common)
+		
 		maps = detect_sizes(probe, [1, 2, 4, 8], ['CHAR', 'SHORT', 'INT', 'LONG', 'LLONG'], ['LONG_DOUBLE', 'DOUBLE', 'FLOAT'])
 		
@@ -851,7 +949,7 @@
 	
 	common['AUTOGEN'] = "%s/autogen.py" % os.path.dirname(os.path.abspath(sys.argv[0]))
-
+	
 	create_makefile(MAKEFILE, common)
-	create_header(HEADER, maps)
+	create_header(HEADER, maps, int128)
 	
 	return 0
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -142,4 +142,5 @@
 	drv/block/ahci \
 	drv/block/ata_bd \
+	drv/block/ddisk \
 	drv/char/i8042 \
 	drv/char/pl050 \
@@ -182,8 +183,13 @@
 
 ifeq ($(UARCH), $(filter $(UARCH),mips32 mips32eb))
+ifeq ($(MACHINE),msim)
+	DIRS += \
+		drv/platform/msim
+else
 	DIRS += \
 		drv/platform/malta \
 		drv/bus/pci/pciintel \
 		drv/bus/isa
+endif
 endif
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/Makefile.common	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -249,10 +249,9 @@
 # something won't break because of that:
 # -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) -finput-charset=UTF-8
-CLANG_CFLAGS = $(LIBC_INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
+CLANG_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
 	-ffreestanding -fno-builtin -nostdlib -nostdinc \
 	-Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
-	-Werror-implicit-function-declaration -Wwrite-strings \
-	-integrated-as \
-	-pipe -g -target $(CLANG_TARGET) -D__$(ENDIANESS)__
+	-std=gnu99 -Werror-implicit-function-declaration -Wwrite-strings \
+	-integrated-as -pipe -g -target $(CLANG_TARGET) -D__$(ENDIANESS)__
 
 LIB_CFLAGS = $(CFLAGS) -fPIC -D__IN_SHARED_LIBC__
@@ -292,26 +291,25 @@
 
 ifeq ($(COMPILER),gcc_cross)
-	CFLAGS += $(GCC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS += $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),gcc_helenos)
-	CFLAGS += $(GCC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS += $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),gcc_native)
-	CFLAGS += $(GCC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS += $(GCC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),icc)
-	CFLAGS += $(ICC_CFLAGS) $(EXTRA_CFLAGS)
+	CFLAGS += $(ICC_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
 
 ifeq ($(COMPILER),clang)
-	CFLAGS += $(CLANG_CFLAGS) $(EXTRA_CFLAGS)
-	GCC_CFLAGS += $(EXTRA_CFLAGS)
+	CFLAGS += $(CLANG_CFLAGS)
 	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
 endif
@@ -375,7 +373,7 @@
 
 %.o: %.S $(DEPEND)
-	$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c $< -o $@
-ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) -D__ASM__
+	$(GCC) $(DEFS) $(GCC_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__ -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
 endif
 
@@ -387,19 +385,19 @@
 
 %.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
-ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS)
 endif
 
 %.test.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(TEST_CFLAGS) -c $< -o $@
-ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
+	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS) -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS)
 endif
 
 %.lo: %.S $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) -D__ASM__ -c $< -o $@
-ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) -D__ASM__
+	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__ -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
 endif
 
@@ -411,11 +409,11 @@
 
 %.lo: %.c $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) -c $< -o $@
-ifeq ($(PRECHECK),y)
-	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS)
+	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+ifeq ($(PRECHECK),y)
+	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS)
 endif
 
 $(DEPEND): $(PRE_DEPEND)
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) $(TEST_SOURCES) > $@ 2> /dev/null
+	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -- $(SOURCES) $(TEST_SOURCES) > $@ 2> /dev/null
 	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
 
Index: uspace/app/barber/barber.c
===================================================================
--- uspace/app/barber/barber.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/barber/barber.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -233,5 +233,5 @@
 	getuptime(&cur);
 	
-	plan_frame_timer(tv_sub(&cur, &prev));
+	plan_frame_timer(tv_sub_diff(&cur, &prev));
 }
 
@@ -308,5 +308,6 @@
 	
 	winreg = argv[1];
-	window_t *main_window = window_open(argv[1], true, true, "barber");
+	window_t *main_window = window_open(argv[1],
+	    WINDOW_MAIN | WINDOW_DECORATED, "barber");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
Index: uspace/app/fontviewer/fontviewer.c
===================================================================
--- uspace/app/fontviewer/fontviewer.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/fontviewer/fontviewer.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -260,5 +260,5 @@
 	}
 	
-	main_window = window_open(argv[1], true, false, "fontviewer");
+	main_window = window_open(argv[1], WINDOW_MAIN, "fontviewer");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
Index: uspace/app/nettest1/nettest1.c
===================================================================
--- uspace/app/nettest1/nettest1.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/nettest1/nettest1.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -412,5 +412,5 @@
 	gettimeofday(&time_after, NULL);
 	
-	printf("Tested in %ld microseconds\n", tv_sub(&time_after,
+	printf("Tested in %ld microseconds\n", tv_sub_diff(&time_after,
 	    &time_before));
 	
Index: uspace/app/nettest2/nettest2.c
===================================================================
--- uspace/app/nettest2/nettest2.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/nettest2/nettest2.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -370,5 +370,5 @@
 	
 	printf("sendto + recvfrom tested in %ld microseconds\n",
-	    tv_sub(&time_after, &time_before));
+	    tv_sub_diff(&time_after, &time_before));
 	
 	gettimeofday(&time_before, NULL);
@@ -390,5 +390,5 @@
 	
 	printf("sendto, recvfrom tested in %ld microseconds\n",
-	    tv_sub(&time_after, &time_before));
+	    tv_sub_diff(&time_after, &time_before));
 	
 	rc = sockets_close(verbose, socket_ids, sockets);
Index: uspace/app/rcubench/rcubench.c
===================================================================
--- uspace/app/rcubench/rcubench.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/rcubench/rcubench.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -264,5 +264,5 @@
 	
 	getuptime(&end);
-	int64_t duration = tv_sub(&end, &start);
+	int64_t duration = tv_sub_diff(&end, &start);
 	
 	uint64_t secs = (uint64_t)duration / 1000 / 1000;
Index: uspace/app/taskdump/fibrildump.c
===================================================================
--- uspace/app/taskdump/fibrildump.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/taskdump/fibrildump.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -81,4 +81,12 @@
 	int rc;
 
+	/* 
+	 * If we for whatever reason could not obtain symbols table from the binary,
+	 * we cannot dump fibrils.
+	 */
+	if (symtab == NULL) {
+		return EIO;
+	}
+
 	rc = symtab_name_to_addr(symtab, "fibril_list", &fibril_list_addr);
 	if (rc != EOK)
Index: uspace/app/tester/float/softfloat1.c
===================================================================
--- uspace/app/tester/float/softfloat1.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/tester/float/softfloat1.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -29,5 +29,5 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <sftypes.h>
+#include <mathtypes.h>
 #include <add.h>
 #include <sub.h>
@@ -39,6 +39,28 @@
 #include "../tester.h"
 
+#define add_float  __addsf3
+#define sub_float  __subsf3
+#define mul_float  __mulsf3
+#define div_float  __divsf3
+
+#define is_float_lt  __ltsf2
+#define is_float_gt  __gtsf2
+#define is_float_eq  __eqsf2
+
+#define add_double  __adddf3
+#define sub_double  __subdf3
+#define mul_double  __muldf3
+#define div_double  __divdf3
+
+#define is_double_lt  __ltdf2
+#define is_double_gt  __gtdf2
+#define is_double_eq  __eqdf2
+
+#define uint_to_double  __floatsidf
+#define double_to_uint  __fixunsdfsi
+#define double_to_int   __fixdfsi
+
 #define OPERANDS   10
-#define PRECISION  10000
+#define PRECISION  1000
 
 #define PRIdCMPTYPE  PRId32
@@ -46,8 +68,9 @@
 typedef int32_t cmptype_t;
 
-typedef void (* uint_to_double_op_t)(unsigned int, double *, double_t *);
+typedef void (* uint_to_double_op_t)(unsigned int, double *, double *);
 typedef void (* double_to_uint_op_t)(double, unsigned int *, unsigned int *);
-typedef void (* float_binary_op_t)(float, float, float *, float_t *);
-typedef void (* double_binary_op_t)(double, double, double *, double_t *);
+typedef void (* float_binary_op_t)(float, float, float *, float *);
+typedef void (* float_cmp_op_t)(float, float, cmptype_t *, cmptype_t *);
+typedef void (* double_binary_op_t)(double, double, double *, double *);
 typedef void (* double_cmp_op_t)(double, double, cmptype_t *, cmptype_t *);
 
@@ -68,16 +91,8 @@
 
 static unsigned int uop_a[OPERANDS] = {
-	4, -100, 100, 50, 1024, 0, 1000000, -1U, 0x80000000U, 500
+	4, 2, 100, 50, 1024, 0, 1000000, 1, 0x8000000, 500
 };
 
-static cmptype_t cmpabs(cmptype_t a)
-{
-	if (a >= 0)
-		return a;
-	
-	return -a;
-}
-
-static int dcmp(double a, double b)
+static int fcmp(float a, float b)
 {
 	if (a < b)
@@ -90,4 +105,15 @@
 }
 
+static int dcmp(double a, double b)
+{
+	if (a < b)
+		return -1;
+	
+	if (a > b)
+		return 1;
+	
+	return 0;
+}
+
 static void uint_to_double_template(void *f, unsigned i, cmptype_t *pic,
     cmptype_t *pisc)
@@ -96,9 +122,9 @@
 	
 	double c;
-	double_t sc;
+	double sc;
 	op(uop_a[i], &c, &sc);
 	
 	*pic = (cmptype_t) (c * PRECISION);
-	*pisc = (cmptype_t) (sc.val * PRECISION);
+	*pisc = (cmptype_t) (sc * PRECISION);
 }
 
@@ -116,5 +142,4 @@
 }
 
-
 static void float_template_binary(void *f, unsigned i, unsigned j,
     cmptype_t *pic, cmptype_t *pisc)
@@ -123,9 +148,17 @@
 	
 	float c;
-	float_t sc;
+	float sc;
 	op(fop_a[i], fop_a[j], &c, &sc);
 	
 	*pic = (cmptype_t) (c * PRECISION);
-	*pisc = (cmptype_t) (sc.val * PRECISION);
+	*pisc = (cmptype_t) (sc * PRECISION);
+}
+
+static void float_compare_template(void *f, unsigned i, unsigned j,
+    cmptype_t *pis, cmptype_t *piss)
+{
+	float_cmp_op_t op = (float_cmp_op_t) f;
+	
+	op(dop_a[i], dop_a[j], pis, piss);
 }
 
@@ -136,9 +169,9 @@
 	
 	double c;
-	double_t sc;
+	double sc;
 	op(dop_a[i], dop_a[j], &c, &sc);
 	
 	*pic = (cmptype_t) (c * PRECISION);
-	*pisc = (cmptype_t) (sc.val * PRECISION);
+	*pisc = (cmptype_t) (sc * PRECISION);
 }
 
@@ -160,8 +193,9 @@
 		
 		template(f, i, &ic, &isc);
-		cmptype_t diff = cmpabs(ic - isc);
+		cmptype_t diff = ic - isc;
 		
 		if (diff != 0) {
-			TPRINTF("i=%u diff=%" PRIdCMPTYPE "\n", i, diff);
+			TPRINTF("i=%u ic=%" PRIdCMPTYPE " isc=%" PRIdCMPTYPE "\n",
+			    i, ic, isc);
 			correct = false;
 		}
@@ -181,9 +215,9 @@
 			
 			template(f, i, j, &ic, &isc);
-			cmptype_t diff = cmpabs(ic - isc);
+			cmptype_t diff = ic - isc;
 			
 			if (diff != 0) {
-				TPRINTF("i=%u, j=%u diff=%" PRIdCMPTYPE "\n",
-				    i, j, diff);
+				TPRINTF("i=%u, j=%u ic=%" PRIdCMPTYPE
+				    " isc=%" PRIdCMPTYPE "\n", i, j, ic, isc);
 				correct = false;
 			}
@@ -194,8 +228,8 @@
 }
 
-static void uint_to_double_operator(unsigned int a, double *pc, double_t *psc)
+static void uint_to_double_operator(unsigned int a, double *pc, double *psc)
 {
 	*pc = (double) a;
-	psc->data = uint_to_double(a);
+	*psc = uint_to_double(a);
 }
 
@@ -203,10 +237,6 @@
     unsigned int *psc)
 {
-	double_t sa;
-	
-	sa.val = a;
-	
 	*pc = (unsigned int) a;
-	*psc = double_to_uint(sa.data);
+	*psc = double_to_uint(a);
 }
 
@@ -214,130 +244,48 @@
     unsigned int *psc)
 {
-	double_t sa;
-	
-	sa.val = a;
-	
 	*pc = (int) a;
-	*psc = double_to_int(sa.data);
-}
-
-static void float_add_operator(float a, float b, float *pc, float_t *psc)
+	*psc = double_to_int(a);
+}
+
+static void float_add_operator(float a, float b, float *pc, float *psc)
 {
 	*pc = a + b;
-	
-	float_t sa;
-	float_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	
-	if (sa.data.parts.sign == sb.data.parts.sign) {
-		psc->data = add_float(sa.data, sb.data);
-	} else if (sa.data.parts.sign) {
-		sa.data.parts.sign = 0;
-		psc->data = sub_float(sb.data, sa.data);
-	} else {
-		sb.data.parts.sign = 0;
-		psc->data = sub_float(sa.data, sb.data);
-	}
-}
-
-static void float_mul_operator(float a, float b, float *pc, float_t *psc)
+	*psc = add_float(a, b);
+}
+
+static void float_sub_operator(float a, float b, float *pc, float *psc)
+{
+	*pc = a - b;
+	*psc = sub_float(a, b);
+}
+
+static void float_mul_operator(float a, float b, float *pc, float *psc)
 {
 	*pc = a * b;
-	
-	float_t sa;
-	float_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	psc->data = mul_float(sa.data, sb.data);
-}
-
-static void float_div_operator(float a, float b, float *pc, float_t *psc)
+	*psc = mul_float(a, b);
+}
+
+static void float_div_operator(float a, float b, float *pc, float *psc)
 {
 	if ((cmptype_t) b == 0) {
 		*pc = 0.0;
-		psc->val = 0.0;
+		*psc = 0.0;
 		return;
 	}
 	
 	*pc = a / b;
-	
-	float_t sa;
-	float_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	psc->data = div_float(sa.data, sb.data);
-}
-
-static void double_add_operator(double a, double b, double *pc, double_t *psc)
-{
-	*pc = a + b;
-	
-	double_t sa;
-	double_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	
-	if (sa.data.parts.sign == sb.data.parts.sign) {
-		psc->data = add_double(sa.data, sb.data);
-	} else if (sa.data.parts.sign) {
-		sa.data.parts.sign = 0;
-		psc->data = sub_double(sb.data, sa.data);
-	} else {
-		sb.data.parts.sign = 0;
-		psc->data = sub_double(sa.data, sb.data);
-	}
-}
-
-static void double_mul_operator(double a, double b, double *pc, double_t *psc)
-{
-	*pc = a * b;
-	
-	double_t sa;
-	double_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	psc->data = mul_double(sa.data, sb.data);
-}
-
-static void double_div_operator(double a, double b, double *pc, double_t *psc)
-{
-	if ((cmptype_t) b == 0) {
-		*pc = 0.0;
-		psc->val = 0.0;
-		return;
-	}
-	
-	*pc = a / b;
-	
-	double_t sa;
-	double_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	psc->data = div_double(sa.data, sb.data);
-}
-
-static void double_cmp_operator(double a, double b, cmptype_t *pis,
+	*psc = div_float(a, b);
+}
+
+static void float_cmp_operator(float a, float b, cmptype_t *pis,
     cmptype_t *piss)
 {
-	*pis = dcmp(a, b);
-	
-	double_t sa;
-	double_t sb;
-	
-	sa.val = a;
-	sb.val = b;
-	
-	if (is_double_lt(sa.data, sb.data))
+	*pis = fcmp(a, b);
+	
+	if (is_float_lt(a, b) == -1)
 		*piss = -1;
-	else if (is_double_gt(sa.data, sb.data))
+	else if (is_float_gt(a, b) == 1)
 		*piss = 1;
-	else if (is_double_eq(sa.data, sb.data))
+	else if (is_float_eq(a, b) == 0)
 		*piss = 0;
 	else
@@ -345,61 +293,124 @@
 }
 
+static void double_add_operator(double a, double b, double *pc, double *psc)
+{
+	*pc = a + b;
+	*psc = add_double(a, b);
+}
+
+static void double_sub_operator(double a, double b, double *pc, double *psc)
+{
+	*pc = a - b;
+	*psc = sub_double(a, b);
+}
+
+static void double_mul_operator(double a, double b, double *pc, double *psc)
+{
+	*pc = a * b;
+	*psc = mul_double(a, b);
+}
+
+static void double_div_operator(double a, double b, double *pc, double *psc)
+{
+	if ((cmptype_t) b == 0) {
+		*pc = 0.0;
+		*psc = 0.0;
+		return;
+	}
+	
+	*pc = a / b;
+	*psc = div_double(a, b);
+}
+
+static void double_cmp_operator(double a, double b, cmptype_t *pis,
+    cmptype_t *piss)
+{
+	*pis = dcmp(a, b);
+	
+	if (is_double_lt(a, b) == -1)
+		*piss = -1;
+	else if (is_double_gt(a, b) == 1)
+		*piss = 1;
+	else if (is_double_eq(a, b) == 0)
+		*piss = 0;
+	else
+		*piss = 42;
+}
+
 const char *test_softfloat1(void)
 {
-	const char *err = NULL;
+	bool err = false;
 	
 	if (!test_template_binary(float_template_binary, float_add_operator)) {
-		err = "Float addition failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Float addition failed");
+	}
+	
+	if (!test_template_binary(float_template_binary, float_sub_operator)) {
+		err = true;
+		TPRINTF("%s\n", "Float addition failed");
 	}
 	
 	if (!test_template_binary(float_template_binary, float_mul_operator)) {
-		err = "Float multiplication failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Float multiplication failed");
 	}
 	
 	if (!test_template_binary(float_template_binary, float_div_operator)) {
-		err = "Float division failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Float division failed");
+	}
+	
+	if (!test_template_binary(float_compare_template, float_cmp_operator)) {
+		err = true;
+		TPRINTF("%s\n", "Float comparison failed");
 	}
 	
 	if (!test_template_binary(double_template_binary, double_add_operator)) {
-		err = "Double addition failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Double addition failed");
+	}
+	
+	if (!test_template_binary(double_template_binary, double_sub_operator)) {
+		err = true;
+		TPRINTF("%s\n", "Double addition failed");
 	}
 	
 	if (!test_template_binary(double_template_binary, double_mul_operator)) {
-		err = "Double multiplication failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Double multiplication failed");
 	}
 	
 	if (!test_template_binary(double_template_binary, double_div_operator)) {
-		err = "Double division failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Double division failed");
 	}
 	
 	if (!test_template_binary(double_compare_template, double_cmp_operator)) {
-		err = "Double comparison failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Double comparison failed");
 	}
 	
 	if (!test_template_unary(uint_to_double_template,
 	    uint_to_double_operator)) {
-		err = "Conversion from unsigned int to double failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Conversion from unsigned int to double failed");
 	}
 	
 	if (!test_template_unary(double_to_uint_template,
 	    double_to_uint_operator)) {
-		err = "Conversion from double to unsigned int failed";
-		TPRINTF("%s\n", err);
+		err = true;
+		TPRINTF("%s\n", "Conversion from double to unsigned int failed");
 	}
 	
 	if (!test_template_unary(double_to_uint_template,
 	    double_to_int_operator)) {
-		err = "Conversion from double to signed int failed";
-		TPRINTF("%s\n", err);
-	}
-	
-	return err;
-}
+		err = true;
+		TPRINTF("%s\n", "Conversion from double to signed int failed");
+	}
+	
+	if (err)
+		return "Software floating point imprecision";
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/ping_pong.c
===================================================================
--- uspace/app/tester/ipc/ping_pong.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/tester/ipc/ping_pong.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -50,5 +50,5 @@
 		gettimeofday(&now, NULL);
 		
-		if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L)
+		if (tv_sub_diff(&now, &start) >= DURATION_SECS * 1000000L)
 			break;
 		
Index: uspace/app/tester/ipc/starve.c
===================================================================
--- uspace/app/tester/ipc/starve.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/tester/ipc/starve.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -52,5 +52,5 @@
 		gettimeofday(&now, NULL);
 		
-		if (tv_sub(&now, &start) >= DURATION_SECS * 1000000L)
+		if (tv_sub_diff(&now, &start) >= DURATION_SECS * 1000000L)
 			break;
 		
Index: uspace/app/vdemo/vdemo.c
===================================================================
--- uspace/app/vdemo/vdemo.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/vdemo/vdemo.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -110,5 +110,6 @@
 {
 	if (argc >= 2) {
-		window_t *main_window = window_open(argv[1], true, true, "vdemo");
+		window_t *main_window = window_open(argv[1],
+		    WINDOW_MAIN | WINDOW_DECORATED | WINDOW_RESIZEABLE, "vdemo");
 		if (!main_window) {
 			printf("Cannot open main window.\n");
Index: uspace/app/viewer/viewer.c
===================================================================
--- uspace/app/viewer/viewer.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/viewer/viewer.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -167,5 +167,5 @@
 	}
 	
-	main_window = window_open(argv[1], true, false, "viewer");
+	main_window = window_open(argv[1], WINDOW_MAIN, "viewer");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
Index: uspace/app/vlaunch/vlaunch.c
===================================================================
--- uspace/app/vlaunch/vlaunch.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/vlaunch/vlaunch.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -114,5 +114,6 @@
 	
 	winreg = argv[1];
-	window_t *main_window = window_open(argv[1], true, true, "vlaunch");
+	window_t *main_window = window_open(argv[1],
+	    WINDOW_MAIN | WINDOW_DECORATED | WINDOW_RESIZEABLE, "vlaunch");
 	if (!main_window) {
 		printf("Cannot open main window.\n");
Index: uspace/app/vterm/vterm.c
===================================================================
--- uspace/app/vterm/vterm.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/vterm/vterm.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -49,5 +49,6 @@
 	}
 	
-	window_t *main_window = window_open(argv[1], true, true, "vterm");
+	window_t *main_window = window_open(argv[1],
+	    WINDOW_MAIN | WINDOW_DECORATED, "vterm");
 	if (!main_window) {
 		printf("%s: Cannot open main window.\n", NAME);
Index: uspace/app/wavplay/drec.c
===================================================================
--- uspace/app/wavplay/drec.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/wavplay/drec.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -47,5 +47,5 @@
 
 
-#define BUFFER_PARTS   2
+#define BUFFER_PARTS   16
 
 /** Recording format */
@@ -103,7 +103,7 @@
 			printf("Recording terminated\n");
 			record = false;
+			break;
 		case PCM_EVENT_FRAMES_CAPTURED:
 			printf("%" PRIun " frames\n", IPC_GET_ARG1(call));
-			async_answer_0(callid, EOK);
 			break;
 		default:
@@ -111,5 +111,9 @@
 			async_answer_0(callid, ENOTSUP);
 			continue;
-
+		}
+
+		if (!record) {
+			async_answer_0(callid, EOK);
+			break;
 		}
 
@@ -156,4 +160,8 @@
 	printf("\n");
 	audio_pcm_stop_capture(rec->device);
+	/* XXX Control returns even before we can be sure callbacks finished */
+	printf("Delay before playback termination\n");
+	async_usleep(1000000);
+	printf("Terminate playback\n");
 }
 
Index: uspace/app/wavplay/main.c
===================================================================
--- uspace/app/wavplay/main.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/wavplay/main.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -308,4 +308,5 @@
 			if (direct) {
 				drecord(device, file);
+				continue;
 			} else {
 				printf("Indirect recording is not supported "
Index: uspace/app/wavplay/wave.c
===================================================================
--- uspace/app/wavplay/wave.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/app/wavplay/wave.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -116,5 +116,5 @@
 		*channels = uint16_t_le2host(header->channels);
 	if (format) {
-		const unsigned size = uint32_t_le2host(header->sample_size);
+		const unsigned size = uint16_t_le2host(header->sample_size);
 		switch (size) {
 		case 8: *format = PCM_SAMPLE_UINT8; break;
@@ -157,5 +157,5 @@
 	header->channels = host2uint32_t_le(format.channels);
 	header->sample_size =
-	    host2uint32_t_le(pcm_sample_format_size(format.sample_format));
+	    host2uint16_t_le(pcm_sample_format_size(format.sample_format) * 8);
 }
 /**
Index: uspace/drv/audio/hdaudio/codec.c
===================================================================
--- uspace/drv/audio/hdaudio/codec.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/codec.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -437,4 +437,9 @@
 	}
 
+	if ((pcaps & BIT_V(uint32_t, pwc_input)) != 0) {
+		ddf_msg(LVL_NOTE, "PIN %d will enable input", aw);
+	    	pctl = pctl | BIT_V(uint8_t, pctl_in_enable);
+	}
+
 	if ((pcaps & BIT_V(uint32_t, pwc_hpd)) != 0) {
 		ddf_msg(LVL_NOTE, "PIN %d will enable headphone drive", aw);
@@ -503,4 +508,5 @@
 	codec->hda = hda;
 	codec->address = address;
+	codec->in_aw = -1;
 
 	rc = hda_get_subnc(codec, 0, &sfg, &nfg);
@@ -587,4 +593,24 @@
 				ddf_msg(LVL_NOTE, "Output widget %d: rates=0x%x formats=0x%x",
 				    aw, rates, formats);
+			} else if (awtype == awt_audio_input) {
+				if (codec->in_aw < 0) {
+					ddf_msg(LVL_NOTE, "Selected input "
+					    "widget %d\n", aw);
+					codec->in_aw = aw;
+				} else {
+					ddf_msg(LVL_NOTE, "Ignoring input "
+					    "widget %d\n", aw);
+				}
+
+				rc = hda_get_supp_rates(codec, aw, &rates);
+				if (rc != EOK)
+					goto error;
+
+				rc = hda_get_supp_formats(codec, aw, &formats);
+				if (rc != EOK)
+					goto error;
+
+				ddf_msg(LVL_NOTE, "Input widget %d: rates=0x%x formats=0x%x",
+				    aw, rates, formats);
 			}
 
@@ -623,14 +649,35 @@
 		/* Configure converter */
 
-		ddf_msg(LVL_NOTE, "Configure converter format");
+		ddf_msg(LVL_NOTE, "Configure output converter format");
 		rc = hda_set_converter_fmt(codec, out_aw, stream->fmt);
 		if (rc != EOK)
 			goto error;
 
-		ddf_msg(LVL_NOTE, "Configure converter stream, channel");
+		ddf_msg(LVL_NOTE, "Configure output converter stream, channel");
 		rc = hda_set_converter_ctl(codec, out_aw, stream->sid, 0);
 		if (rc != EOK)
 			goto error;
 	}
+
+	return EOK;
+error:
+	return rc;
+}
+
+int hda_in_converter_setup(hda_codec_t *codec, hda_stream_t *stream)
+{
+	int rc;
+
+	/* Configure converter */
+
+	ddf_msg(LVL_NOTE, "Configure input converter format");
+	rc = hda_set_converter_fmt(codec, codec->in_aw, stream->fmt);
+	if (rc != EOK)
+		goto error;
+
+	ddf_msg(LVL_NOTE, "Configure input converter stream, channel");
+	rc = hda_set_converter_ctl(codec, codec->in_aw, stream->sid, 0);
+	if (rc != EOK)
+		goto error;
 
 	return EOK;
Index: uspace/drv/audio/hdaudio/codec.h
===================================================================
--- uspace/drv/audio/hdaudio/codec.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/codec.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -47,4 +47,5 @@
 	int out_aw_num;
 	int out_aw_sel;
+	int in_aw;
 } hda_codec_t;
 
@@ -52,4 +53,5 @@
 extern void hda_codec_fini(hda_codec_t *);
 extern int hda_out_converter_setup(hda_codec_t *, hda_stream_t *);
+extern int hda_in_converter_setup(hda_codec_t *, hda_stream_t *);
 
 #endif
Index: uspace/drv/audio/hdaudio/hdactl.c
===================================================================
--- uspace/drv/audio/hdaudio/hdactl.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/hdactl.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -562,5 +562,6 @@
 	ctl->bss = BIT_RANGE_EXTRACT(uint16_t, gcap_bss_h, gcap_bss_l, gcap);
 	ddf_msg(LVL_NOTE, "GCAP: 0x%x (64OK=%d)", gcap, ctl->ok64bit);
-
+	ddf_msg(LVL_NOTE, "iss: %d, oss: %d, bss: %d\n",
+	    ctl->iss, ctl->oss, ctl->bss);
 	/* Give codecs enough time to enumerate themselves */
 	async_usleep(codec_enum_wait_us);
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -385,5 +385,11 @@
 			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
 			hda_pcm_event(hda, PCM_EVENT_FRAMES_PLAYED);
+		} else if (hda->capturing) {
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_CAPTURED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_CAPTURED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_CAPTURED);
+			hda_pcm_event(hda, PCM_EVENT_FRAMES_CAPTURED);
 		}
+
 		hda_unlock(hda);
 	}
Index: uspace/drv/audio/hdaudio/hdaudio.h
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/hdaudio.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -55,5 +55,7 @@
 	struct hda_ctl *ctl;
 	struct hda_stream *pcm_stream;
+	struct hda_stream_buffers *pcm_buffers;
 	bool playing;
+	bool capturing;
 } hda_t;
 
Index: uspace/drv/audio/hdaudio/pcm_iface.c
===================================================================
--- uspace/drv/audio/hdaudio/pcm_iface.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/pcm_iface.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -100,11 +100,16 @@
 static unsigned hda_query_cap(ddf_fun_t *fun, audio_cap_t cap)
 {
+	hda_t *hda = fun_to_hda(fun);
+
 	ddf_msg(LVL_NOTE, "hda_query_cap(%d)", cap);
 	switch (cap) {
 	case AUDIO_CAP_PLAYBACK:
 	case AUDIO_CAP_INTERRUPT:
+		/* XXX Only if we have an output converter */
 		return 1;
+	case AUDIO_CAP_CAPTURE:
+		/* Yes if we have an input converter */
+		return hda->ctl->codec->in_aw >= 0;
 	case AUDIO_CAP_BUFFER_POS:
-	case AUDIO_CAP_CAPTURE:
 		return 0;
 	case AUDIO_CAP_MAX_BUFFER:
@@ -148,8 +153,94 @@
 {
 	hda_t *hda = fun_to_hda(fun);
+	int rc;
 
 	hda_lock(hda);
 
 	ddf_msg(LVL_NOTE, "hda_get_buffer(): hda=%p", hda);
+	if (hda->pcm_buffers != NULL) {
+		hda_unlock(hda);
+		return EBUSY;
+	}
+
+	ddf_msg(LVL_NOTE, "hda_get_buffer() - allocate stream buffers");
+	rc = hda_stream_buffers_alloc(hda, &hda->pcm_buffers);
+	if (rc != EOK) {
+		assert(rc == ENOMEM);
+		hda_unlock(hda);
+		return ENOMEM;
+	}
+
+	ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
+	/* XXX This is only one buffer */
+	*buffer = hda->pcm_buffers->buf[0];
+	*size = hda->pcm_buffers->bufsize * hda->pcm_buffers->nbuffers;
+
+	ddf_msg(LVL_NOTE, "hda_get_buffer() returing EOK, buffer=%p, size=%zu",
+	    *buffer, *size);
+
+	hda_unlock(hda);
+	return EOK;
+}
+
+static int hda_get_buffer_position(ddf_fun_t *fun, size_t *pos)
+{
+	ddf_msg(LVL_NOTE, "hda_get_buffer_position()");
+	return ENOTSUP;
+}
+
+static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess)
+{
+	hda_t *hda = fun_to_hda(fun);
+
+	ddf_msg(LVL_NOTE, "hda_set_event_session()");
+	hda_lock(hda);
+	hda->ev_sess = sess;
+	hda_unlock(hda);
+
+	return EOK;
+}
+
+static async_sess_t *hda_get_event_session(ddf_fun_t *fun)
+{
+	hda_t *hda = fun_to_hda(fun);
+	async_sess_t *sess;
+
+	ddf_msg(LVL_NOTE, "hda_get_event_session()");
+
+	hda_lock(hda);
+	sess = hda->ev_sess;
+	hda_unlock(hda);
+
+	return sess;
+}
+
+static int hda_release_buffer(ddf_fun_t *fun)
+{
+	hda_t *hda = fun_to_hda(fun);
+
+	hda_lock(hda);
+
+	ddf_msg(LVL_NOTE, "hda_release_buffer()");
+	if (hda->pcm_buffers == NULL) {
+		hda_unlock(hda);
+		return EINVAL;
+	}
+
+	hda_stream_buffers_free(hda->pcm_buffers);
+	hda->pcm_buffers = NULL;
+
+	hda_unlock(hda);
+	return EOK;
+}
+
+static int hda_start_playback(ddf_fun_t *fun, unsigned frames,
+    unsigned channels, unsigned rate, pcm_sample_format_t format)
+{
+	hda_t *hda = fun_to_hda(fun);
+	int rc;
+
+	ddf_msg(LVL_NOTE, "hda_start_playback()");
+	hda_lock(hda);
+
 	if (hda->pcm_stream != NULL) {
 		hda_unlock(hda);
@@ -162,91 +253,22 @@
 	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1;
 
-	ddf_msg(LVL_NOTE, "hda_get_buffer() - create stream");
-	hda->pcm_stream = hda_stream_create(hda, sdir_output, fmt);
+	ddf_msg(LVL_NOTE, "hda_start_playback() - create output stream");
+	hda->pcm_stream = hda_stream_create(hda, sdir_output, hda->pcm_buffers,
+	    fmt);
 	if (hda->pcm_stream == NULL) {
 		hda_unlock(hda);
 		return EIO;
 	}
-
-	ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
-	/* XXX This is only one buffer */
-	*buffer = hda->pcm_stream->buf[0];
-	*size = hda->pcm_stream->bufsize * hda->pcm_stream->nbuffers;
-
-	ddf_msg(LVL_NOTE, "hda_get_buffer() retturing EOK, buffer=%p, size=%zu",
-	    *buffer, *size);
-
-	hda_unlock(hda);
-	return EOK;
-}
-
-static int hda_get_buffer_position(ddf_fun_t *fun, size_t *pos)
-{
-	ddf_msg(LVL_NOTE, "hda_get_buffer_position()");
-	return ENOTSUP;
-}
-
-static int hda_set_event_session(ddf_fun_t *fun, async_sess_t *sess)
-{
-	hda_t *hda = fun_to_hda(fun);
-
-	ddf_msg(LVL_NOTE, "hda_set_event_session()");
-	hda_lock(hda);
-	hda->ev_sess = sess;
-	hda_unlock(hda);
-
-	return EOK;
-}
-
-static async_sess_t *hda_get_event_session(ddf_fun_t *fun)
-{
-	hda_t *hda = fun_to_hda(fun);
-	async_sess_t *sess;
-
-	ddf_msg(LVL_NOTE, "hda_get_event_session()");
-
-	hda_lock(hda);
-	sess = hda->ev_sess;
-	hda_unlock(hda);
-
-	return sess;
-}
-
-static int hda_release_buffer(ddf_fun_t *fun)
-{
-	hda_t *hda = fun_to_hda(fun);
-
-	hda_lock(hda);
-
-	ddf_msg(LVL_NOTE, "hda_release_buffer()");
-	if (hda->pcm_stream == NULL) {
-		hda_unlock(hda);
-		return EINVAL;
-	}
-
-	hda_stream_destroy(hda->pcm_stream);
-	hda->pcm_stream = NULL;
-
-	hda_unlock(hda);
-	return EOK;
-}
-
-static int hda_start_playback(ddf_fun_t *fun, unsigned frames,
-    unsigned channels, unsigned rate, pcm_sample_format_t format)
-{
-	hda_t *hda = fun_to_hda(fun);
-	int rc;
-
-	ddf_msg(LVL_NOTE, "hda_start_playback()");
-	hda_lock(hda);
 
 	rc = hda_out_converter_setup(hda->ctl->codec, hda->pcm_stream);
 	if (rc != EOK) {
+		hda_stream_destroy(hda->pcm_stream);
+		hda->pcm_stream = NULL;
 		hda_unlock(hda);
 		return rc;
 	}
 
+	hda->playing = true;
 	hda_stream_start(hda->pcm_stream);
-	hda->playing = true;
 	hda_unlock(hda);
 	return EOK;
@@ -262,4 +284,7 @@
 	hda_stream_reset(hda->pcm_stream);
 	hda->playing = false;
+	hda_stream_destroy(hda->pcm_stream);
+	hda->pcm_stream = NULL;
+
 	hda_unlock(hda);
 
@@ -271,12 +296,57 @@
     unsigned rate, pcm_sample_format_t format)
 {
+	hda_t *hda = fun_to_hda(fun);
+	int rc;
+
 	ddf_msg(LVL_NOTE, "hda_start_capture()");
-	return ENOTSUP;
+	hda_lock(hda);
+
+	if (hda->pcm_stream != NULL) {
+		hda_unlock(hda);
+		return EBUSY;
+	}
+
+	/* XXX Choose appropriate parameters */
+	uint32_t fmt;
+	/* 48 kHz, 16-bits, 1 channel */
+	fmt = (fmt_base_44khz << fmt_base) | (fmt_bits_16 << fmt_bits_l) | 1;
+
+	ddf_msg(LVL_NOTE, "hda_start_capture() - create input stream");
+	hda->pcm_stream = hda_stream_create(hda, sdir_input, hda->pcm_buffers,
+	    fmt);
+	if (hda->pcm_stream == NULL) {
+		hda_unlock(hda);
+		return EIO;
+	}
+
+	rc = hda_in_converter_setup(hda->ctl->codec, hda->pcm_stream);
+	if (rc != EOK) {
+		hda_stream_destroy(hda->pcm_stream);
+		hda->pcm_stream = NULL;
+		hda_unlock(hda);
+		return rc;
+	}
+
+	hda->capturing = true;
+	hda_stream_start(hda->pcm_stream);
+	hda_unlock(hda);
+	return EOK;
 }
 
 static int hda_stop_capture(ddf_fun_t *fun, bool immediate)
 {
+	hda_t *hda = fun_to_hda(fun);
+
 	ddf_msg(LVL_NOTE, "hda_stop_capture()");
-	return ENOTSUP;
+	hda_lock(hda);
+	hda_stream_stop(hda->pcm_stream);
+	hda_stream_reset(hda->pcm_stream);
+	hda->capturing = false;
+	hda_stream_destroy(hda->pcm_stream);
+	hda->pcm_stream = NULL;
+	hda_unlock(hda);
+
+	hda_pcm_event(hda, PCM_EVENT_CAPTURE_TERMINATED);
+	return EOK;
 }
 
Index: uspace/drv/audio/hdaudio/stream.c
===================================================================
--- uspace/drv/audio/hdaudio/stream.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/stream.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -48,15 +48,22 @@
 #include "stream.h"
 
-static int hda_stream_buffers_alloc(hda_stream_t *stream)
+int hda_stream_buffers_alloc(hda_t *hda, hda_stream_buffers_t **rbufs)
 {
 	void *bdl;
 	void *buffer;
 	uintptr_t buffer_phys;
+	hda_stream_buffers_t *bufs = NULL;
 	size_t i;
 //	size_t j, k;
 	int rc;
 
-	stream->nbuffers = 4;
-	stream->bufsize = 16384;
+	bufs = calloc(1, sizeof(hda_stream_buffers_t));
+	if (bufs == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	bufs->nbuffers = 4;
+	bufs->bufsize = 16384;
 
 	/*
@@ -65,28 +72,28 @@
 	 */
 	bdl = AS_AREA_ANY;
-	rc = dmamem_map_anonymous(stream->nbuffers * sizeof(hda_buffer_desc_t),
-	    stream->hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
-	    0, &stream->bdl_phys, &bdl);
+	rc = dmamem_map_anonymous(bufs->nbuffers * sizeof(hda_buffer_desc_t),
+	    hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
+	    0, &bufs->bdl_phys, &bdl);
 	if (rc != EOK)
 		goto error;
 
-	stream->bdl = bdl;
+	bufs->bdl = bdl;
 
 	/* Allocate arrays of buffer pointers */
 
-	stream->buf = calloc(stream->nbuffers, sizeof(void *));
-	if (stream->buf == NULL)
-		goto error;
-
-	stream->buf_phys = calloc(stream->nbuffers, sizeof(uintptr_t));
-	if (stream->buf_phys == NULL)
+	bufs->buf = calloc(bufs->nbuffers, sizeof(void *));
+	if (bufs->buf == NULL)
+		goto error;
+
+	bufs->buf_phys = calloc(bufs->nbuffers, sizeof(uintptr_t));
+	if (bufs->buf_phys == NULL)
 		goto error;
 
 	/* Allocate buffers */
 /*
-	for (i = 0; i < stream->nbuffers; i++) {
+	for (i = 0; i < bufs->nbuffers; i++) {
 		buffer = AS_AREA_ANY;
-		rc = dmamem_map_anonymous(stream->bufsize,
-		    stream->hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
+		rc = dmamem_map_anonymous(bufs->bufsize,
+		    bufs->hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
 		    0, &buffer_phys, &buffer);
 		if (rc != EOK)
@@ -96,10 +103,10 @@
 		    (unsigned long long)buffer_phys, buffer);
 
-		stream->buf[i] = buffer;
-		stream->buf_phys[i] = buffer_phys;
+		bufs->buf[i] = buffer;
+		bufs->buf_phys[i] = buffer_phys;
 
 		k = 0;
-		for (j = 0; j < stream->bufsize / 2; j++) {
-			int16_t *bp = stream->buf[i];
+		for (j = 0; j < bufs->bufsize / 2; j++) {
+			int16_t *bp = bufs->buf[i];
 			bp[j] = (k > 128) ? -100 : 100;
 			++k;
@@ -111,6 +118,6 @@
 	/* audio_pcm_iface requires a single contiguous buffer */
 	buffer = AS_AREA_ANY;
-	rc = dmamem_map_anonymous(stream->bufsize * stream->nbuffers,
-	    stream->hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
+	rc = dmamem_map_anonymous(bufs->bufsize * bufs->nbuffers,
+	    hda->ctl->ok64bit ? 0 : DMAMEM_4GiB, AS_AREA_READ | AS_AREA_WRITE,
 	    0, &buffer_phys, &buffer);
 	if (rc != EOK) {
@@ -119,14 +126,14 @@
 	}
 
-	for (i = 0; i < stream->nbuffers; i++) {
-		stream->buf[i] = buffer + i * stream->bufsize;
-		stream->buf_phys[i] = buffer_phys + i * stream->bufsize;
+	for (i = 0; i < bufs->nbuffers; i++) {
+		bufs->buf[i] = buffer + i * bufs->bufsize;
+		bufs->buf_phys[i] = buffer_phys + i * bufs->bufsize;
 
 		ddf_msg(LVL_NOTE, "Stream buf phys=0x%llx virt=%p",
-		    (long long unsigned)(uintptr_t)stream->buf[i],
-		    (void *)stream->buf_phys[i]);
+		    (long long unsigned)(uintptr_t)bufs->buf[i],
+		    (void *)bufs->buf_phys[i]);
 /*		k = 0;
-		for (j = 0; j < stream->bufsize / 2; j++) {
-			int16_t *bp = stream->buf[i];
+		for (j = 0; j < bufs->bufsize / 2; j++) {
+			int16_t *bp = bufs->buf[i];
 			bp[j] = (k > 128) ? -10000 : 10000;
 			++k;
@@ -138,18 +145,30 @@
 
 	/* Fill in BDL */
-	for (i = 0; i < stream->nbuffers; i++) {
-		stream->bdl[i].address = host2uint64_t_le(stream->buf_phys[i]);
-		stream->bdl[i].length = host2uint32_t_le(stream->bufsize);
-		stream->bdl[i].flags = BIT_V(uint32_t, bdf_ioc);
-	}
-
+	for (i = 0; i < bufs->nbuffers; i++) {
+		bufs->bdl[i].address = host2uint64_t_le(bufs->buf_phys[i]);
+		bufs->bdl[i].length = host2uint32_t_le(bufs->bufsize);
+		bufs->bdl[i].flags = BIT_V(uint32_t, bdf_ioc);
+	}
+
+	*rbufs = bufs;
 	return EOK;
 error:
+	hda_stream_buffers_free(bufs);
 	return ENOMEM;
 }
 
+void hda_stream_buffers_free(hda_stream_buffers_t *bufs)
+{
+	if (bufs == NULL)
+		return;
+
+	/* XXX */
+	free(bufs);
+}
+
 static void hda_stream_desc_configure(hda_stream_t *stream)
 {
 	hda_sdesc_regs_t *sdregs;
+	hda_stream_buffers_t *bufs = stream->buffers;
 	uint8_t ctl1;
 	uint8_t ctl3;
@@ -161,9 +180,9 @@
 	hda_reg8_write(&sdregs->ctl3, ctl3);
 	hda_reg8_write(&sdregs->ctl1, ctl1);
-	hda_reg32_write(&sdregs->cbl, stream->nbuffers * stream->bufsize);
-	hda_reg16_write(&sdregs->lvi, stream->nbuffers - 1);
+	hda_reg32_write(&sdregs->cbl, bufs->nbuffers * bufs->bufsize);
+	hda_reg16_write(&sdregs->lvi, bufs->nbuffers - 1);
 	hda_reg16_write(&sdregs->fmt, stream->fmt);
-	hda_reg32_write(&sdregs->bdpl, LOWER32(stream->bdl_phys));
-	hda_reg32_write(&sdregs->bdpu, UPPER32(stream->bdl_phys));
+	hda_reg32_write(&sdregs->bdpl, LOWER32(bufs->bdl_phys));
+	hda_reg32_write(&sdregs->bdpu, UPPER32(bufs->bdl_phys));
 }
 
@@ -205,8 +224,8 @@
 
 hda_stream_t *hda_stream_create(hda_t *hda, hda_stream_dir_t dir,
-    uint32_t fmt)
+    hda_stream_buffers_t *bufs, uint32_t fmt)
 {
 	hda_stream_t *stream;
-	int rc;
+	uint8_t sdid;
 
 	stream = calloc(1, sizeof(hda_stream_t));
@@ -214,22 +233,30 @@
 		return NULL;
 
+	sdid = 0;
+
+	switch (dir) {
+	case sdir_input:
+		sdid = 0; /* XXX Allocate - first input SDESC */
+		break;
+	case sdir_output:
+		sdid = hda->ctl->iss; /* XXX Allocate - First output SDESC */
+		break;
+	case sdir_bidi:
+		sdid = hda->ctl->iss + hda->ctl->oss; /* XXX Allocate - First bidi SDESC */
+		break;
+	}
+
 	stream->hda = hda;
 	stream->dir = dir;
 	stream->sid = 1; /* XXX Allocate this */
-	stream->sdid = hda->ctl->iss; /* XXX Allocate - First output SDESC */
+	stream->sdid = sdid;
 	stream->fmt = fmt;
+	stream->buffers = bufs;
 
 	ddf_msg(LVL_NOTE, "snum=%d sdidx=%d", stream->sid, stream->sdid);
-
-	ddf_msg(LVL_NOTE, "Allocate buffers");
-	rc = hda_stream_buffers_alloc(stream);
-	if (rc != EOK)
-		goto error;
 
 	ddf_msg(LVL_NOTE, "Configure stream descriptor");
 	hda_stream_desc_configure(stream);
 	return stream;
-error:
-	return NULL;
 }
 
Index: uspace/drv/audio/hdaudio/stream.h
===================================================================
--- uspace/drv/audio/hdaudio/stream.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/audio/hdaudio/stream.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -48,12 +48,5 @@
 } hda_stream_dir_t;
 
-typedef struct hda_stream {
-	hda_t *hda;
-	/** Stream ID */
-	uint8_t sid;
-	/** Stream descriptor index */
-	uint8_t sdid;
-	/** Direction */
-	hda_stream_dir_t dir;
+typedef struct hda_stream_buffers {
 	/** Number of buffers */
 	size_t nbuffers;
@@ -68,9 +61,24 @@
 	/** Physical addresses of buffers */
 	uintptr_t *buf_phys;
+} hda_stream_buffers_t;
+
+typedef struct hda_stream {
+	hda_t *hda;
+	/** Stream ID */
+	uint8_t sid;
+	/** Stream descriptor index */
+	uint8_t sdid;
+	/** Direction */
+	hda_stream_dir_t dir;
+	/** Buffers */
+	hda_stream_buffers_t *buffers;
 	/** Stream format */
 	uint32_t fmt;
 } hda_stream_t;
 
-extern hda_stream_t *hda_stream_create(hda_t *, hda_stream_dir_t, uint32_t);
+extern int hda_stream_buffers_alloc(hda_t *, hda_stream_buffers_t **);
+extern void hda_stream_buffers_free(hda_stream_buffers_t *);
+extern hda_stream_t *hda_stream_create(hda_t *, hda_stream_dir_t,
+    hda_stream_buffers_t *, uint32_t);
 extern void hda_stream_destroy(hda_stream_t *);
 extern void hda_stream_start(hda_stream_t *);
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/block/ata_bd/main.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -81,5 +81,4 @@
 		rc = EINVAL;
 		goto error;
-		return EINVAL;
 	}
 
Index: uspace/drv/block/ddisk/Makefile
===================================================================
--- uspace/drv/block/ddisk/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/block/ddisk/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2013 Jiri Svoboda
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBSCSI_PREFIX)/libscsi.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBSCSI_PREFIX)/include
+BINARY = ddisk
+
+SOURCES = \
+	ddisk.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/block/ddisk/ddisk.c
===================================================================
--- uspace/drv/block/ddisk/ddisk.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/block/ddisk/ddisk.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,599 @@
+/*
+ * Copyright (c) 2015 Jakub Jermar
+ * Copyright (c) 2013 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @file
+ * MSIM ddisk block device driver
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <ddi.h>
+#include <bd_srv.h>
+#include <fibril_synch.h>
+#include <as.h>
+
+#define NAME	"ddisk"
+
+#define DDISK_FUN_NAME	"a"
+
+#define DDISK_BLOCK_SIZE	512
+
+#define DDISK_STAT_IRQ_PENDING	0x4
+#define DDISK_CMD_READ		0x1
+#define DDISK_CMD_WRITE		0x2
+#define DDISK_CMD_IRQ_DEASSERT	0x4
+
+static int ddisk_dev_add(ddf_dev_t *);
+static int ddisk_dev_remove(ddf_dev_t *);
+static int ddisk_dev_gone(ddf_dev_t *);
+static int ddisk_fun_online(ddf_fun_t *);
+static int ddisk_fun_offline(ddf_fun_t *);
+
+static void ddisk_bd_connection(ipc_callid_t, ipc_call_t *, void *);
+
+static void ddisk_irq_handler(ipc_callid_t, ipc_call_t *, ddf_dev_t *);
+
+static driver_ops_t driver_ops = {
+	.dev_add = ddisk_dev_add,
+	.dev_remove = ddisk_dev_remove,
+	.dev_gone = ddisk_dev_gone,
+	.fun_online = ddisk_fun_online,
+	.fun_offline = ddisk_fun_offline
+};
+
+static driver_t ddisk_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+typedef struct {
+	int irq;
+	uintptr_t base;
+} ddisk_res_t;
+
+typedef struct {
+	ioport32_t dma_buffer;
+	ioport32_t block;
+	union {
+		ioport32_t status;
+		ioport32_t command;
+	};
+	ioport32_t size;
+} ddisk_regs_t;
+
+typedef struct {
+	fibril_mutex_t lock;
+
+	fibril_condvar_t io_cv;
+	bool io_busy;
+
+	ssize_t size;
+	size_t blocks;
+
+	uintptr_t dma_buffer_phys;
+	void *dma_buffer;
+
+	ddf_dev_t *dev;
+	ddf_fun_t *fun;
+
+	ddisk_res_t ddisk_res;
+	ddisk_regs_t *ddisk_regs;
+
+	bd_srvs_t bds;
+} ddisk_t;
+
+static int ddisk_bd_open(bd_srvs_t *, bd_srv_t *);
+static int ddisk_bd_close(bd_srv_t *);
+static int ddisk_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
+static int ddisk_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *,
+    size_t);
+static int ddisk_bd_get_block_size(bd_srv_t *, size_t *);
+static int ddisk_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
+
+bd_ops_t ddisk_bd_ops = {
+	.open = ddisk_bd_open,
+	.close = ddisk_bd_close,
+	.read_blocks = ddisk_bd_read_blocks,
+	.write_blocks = ddisk_bd_write_blocks,
+	.get_block_size = ddisk_bd_get_block_size,
+	.get_num_blocks = ddisk_bd_get_num_blocks,
+};
+
+irq_pio_range_t ddisk_irq_pio_ranges[] = {
+	{
+		.base = 0,
+		.size = sizeof(ddisk_regs_t)
+	}
+};
+
+irq_cmd_t ddisk_irq_commands[] = {
+	{
+		.cmd = CMD_PIO_READ_32,
+		.addr = NULL,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_AND,
+		.srcarg = 1,
+		.value = DDISK_STAT_IRQ_PENDING,
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.srcarg = 2,
+		.value = 2 
+	},
+	{
+		/* Deassert the DMA interrupt. */
+		.cmd = CMD_PIO_WRITE_32,
+		.value = DDISK_CMD_IRQ_DEASSERT,
+		.addr = NULL 
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+irq_code_t ddisk_irq_code = {
+	.rangecount = 1,
+	.ranges = ddisk_irq_pio_ranges,
+	.cmdcount = sizeof(ddisk_irq_commands) / sizeof(irq_cmd_t),
+	.cmds = ddisk_irq_commands,
+};
+
+void ddisk_irq_handler(ipc_callid_t iid, ipc_call_t *icall, ddf_dev_t *dev)
+{
+	ddf_msg(LVL_DEBUG, "ddisk_irq_handler(), status=%" PRIx32,
+	    (uint32_t) IPC_GET_ARG1(*icall));
+
+	ddisk_t *ddisk = (ddisk_t *) ddf_dev_data_get(dev);
+	
+	fibril_mutex_lock(&ddisk->lock);
+	fibril_condvar_broadcast(&ddisk->io_cv);
+	fibril_mutex_unlock(&ddisk->lock);
+}
+
+int ddisk_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
+{
+	return EOK;
+}
+
+int ddisk_bd_close(bd_srv_t *bd)
+{
+	return EOK;
+}
+
+static
+int ddisk_rw_block(ddisk_t *ddisk, bool read, aoff64_t ba, void *buf)
+{
+	fibril_mutex_lock(&ddisk->lock);
+
+	ddf_msg(LVL_DEBUG, "ddisk_rw_block(): read=%d, ba=%" PRId64 ", buf=%p",
+	    read, ba, buf);
+
+	if (ba >= ddisk->blocks)
+		return ELIMIT;
+
+	while (ddisk->io_busy)
+		fibril_condvar_wait(&ddisk->io_cv, &ddisk->lock);
+
+	ddisk->io_busy = true;
+
+	if (!read)
+		memcpy(ddisk->dma_buffer, buf, DDISK_BLOCK_SIZE);
+	
+	pio_write_32(&ddisk->ddisk_regs->dma_buffer,
+	    ddisk->dma_buffer_phys);
+	pio_write_32(&ddisk->ddisk_regs->block, (uint32_t) ba);
+	pio_write_32(&ddisk->ddisk_regs->command,
+	    read ? DDISK_CMD_READ : DDISK_CMD_WRITE);
+
+	fibril_condvar_wait(&ddisk->io_cv, &ddisk->lock);
+
+	if (read)
+		memcpy(buf, ddisk->dma_buffer, DDISK_BLOCK_SIZE);
+
+	ddisk->io_busy = false;
+	fibril_condvar_signal(&ddisk->io_cv);
+	fibril_mutex_unlock(&ddisk->lock);
+
+	return EOK;
+}
+
+static
+int ddisk_bd_rw_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
+    size_t size, bool is_read)
+{
+	ddisk_t *ddisk = (ddisk_t *) bd->srvs->sarg;
+	aoff64_t i;
+	int rc;
+
+	if (size < cnt * DDISK_BLOCK_SIZE)
+		return EINVAL;		
+
+	for (i = 0; i < cnt; i++) {
+		rc = ddisk_rw_block(ddisk, is_read, ba + i,
+		    buf + i * DDISK_BLOCK_SIZE);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
+int ddisk_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt, void *buf,
+    size_t size)
+{
+	return ddisk_bd_rw_blocks(bd, ba, cnt, buf, size, true);
+}
+
+int ddisk_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    const void *buf, size_t size)
+{
+	return ddisk_bd_rw_blocks(bd, ba, cnt, (void *) buf, size, false);
+}
+
+int ddisk_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
+{
+	*rsize = DDISK_BLOCK_SIZE; 
+	return EOK;
+}
+
+int ddisk_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
+{
+	ddisk_t *ddisk = (ddisk_t *) bd->srvs->sarg;
+
+	*rnb = ddisk->blocks;
+	return EOK;	
+}
+
+static int ddisk_get_res(ddf_dev_t *dev, ddisk_res_t *ddisk_res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	int rc;
+
+	parent_sess = ddf_dev_parent_sess_create(dev, EXCHANGE_SERIALIZE);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if ((hw_res.mem_ranges.count != 1) || (hw_res.irqs.count != 1)) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	addr_range_t *regs = &hw_res.mem_ranges.ranges[0];
+	ddisk_res->base = RNGABS(*regs);
+	ddisk_res->irq = hw_res.irqs.irqs[0]; 
+
+	if (RNGSZ(*regs) < sizeof(ddisk_regs_t)) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	rc = EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static int ddisk_fun_create(ddisk_t *ddisk)
+{
+	int rc;
+	ddf_fun_t *fun = NULL;
+
+	fun = ddf_fun_create(ddisk->dev, fun_exposed, DDISK_FUN_NAME);
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating DDF function.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/* Set up a connection handler. */
+	ddf_fun_set_conn_handler(fun, ddisk_bd_connection);
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding DDF function %s: %s",
+		    DDISK_FUN_NAME, str_error(rc));
+		goto error;
+	}
+
+	ddf_fun_add_to_category(fun, "bd");
+	ddisk->fun = fun;
+
+	return EOK;
+error:
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+
+	return rc;
+}
+
+static int ddisk_fun_remove(ddisk_t *ddisk)
+{
+	int rc;
+
+	if (ddisk->fun == NULL)
+		return EOK;
+
+	ddf_msg(LVL_DEBUG, "ddisk_fun_remove(%p, '%s')", ddisk,
+	    DDISK_FUN_NAME);
+	rc = ddf_fun_offline(ddisk->fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error offlining function '%s'.",
+		    DDISK_FUN_NAME);
+		goto error;
+	}
+
+	rc = ddf_fun_unbind(ddisk->fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.",
+		    DDISK_FUN_NAME);
+		goto error;
+	}
+
+	ddf_fun_destroy(ddisk->fun);
+	ddisk->fun = NULL;
+	rc = EOK;
+
+error:
+	return rc;
+}
+
+static int ddisk_fun_unbind(ddisk_t *ddisk)
+{
+	int rc;
+
+	if (ddisk->fun == NULL)
+		return EOK;
+
+	ddf_msg(LVL_DEBUG, "ddisk_fun_unbind(%p, '%s')", ddisk,
+	    DDISK_FUN_NAME);
+	rc = ddf_fun_unbind(ddisk->fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.",
+		    DDISK_FUN_NAME);
+		goto error;
+	}
+
+	ddf_fun_destroy(ddisk->fun);
+	ddisk->fun = NULL;
+	rc = EOK;
+
+error:
+	return rc;
+}
+
+/** Add new device
+ *
+ * @param  dev New device
+ * @return     EOK on success or negative error code.
+ */
+static int ddisk_dev_add(ddf_dev_t *dev)
+{
+	ddisk_t *ddisk;
+	ddisk_res_t res;
+	int rc;
+
+	/*
+	 * Get our resources.
+	 */
+	rc = ddisk_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Invalid HW resource configuration.");
+		return EINVAL;
+	}
+
+	/*
+	 * Allocate soft state.
+	 */
+	ddisk = ddf_dev_data_alloc(dev, sizeof(ddisk_t));
+	if (!ddisk) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	/*
+	 * Initialize soft state.
+	 */
+	fibril_mutex_initialize(&ddisk->lock);
+	ddisk->dev = dev;
+	ddisk->ddisk_res = res;
+
+	fibril_condvar_initialize(&ddisk->io_cv);
+	ddisk->io_busy = false;
+
+	bd_srvs_init(&ddisk->bds);
+	ddisk->bds.ops = &ddisk_bd_ops;
+	ddisk->bds.sarg = ddisk;
+
+	/*
+	 * Enable access to ddisk's PIO registers.
+	 */
+	void *vaddr;
+	rc = pio_enable((void *) res.base, sizeof(ddisk_regs_t), &vaddr);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot initialize device I/O space.");
+		goto error;
+	}
+	ddisk->ddisk_regs = vaddr;
+
+	ddisk->size = (int32_t) pio_read_32(&ddisk->ddisk_regs->size);
+	ddisk->blocks = ddisk->size / DDISK_BLOCK_SIZE;
+
+	if (ddisk->size <= 0) {
+		ddf_msg(LVL_WARN, "No disk detected.");
+		rc = EIO;
+		goto error;
+	}
+
+	/*
+	 * Allocate DMA buffer.
+	 */
+	ddisk->dma_buffer = AS_AREA_ANY;
+	rc = dmamem_map_anonymous(DDISK_BLOCK_SIZE, DMAMEM_4GiB,
+	    AS_AREA_READ | AS_AREA_WRITE, 0, &ddisk->dma_buffer_phys,
+	    &ddisk->dma_buffer);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Cannot allocate DMA memory.");
+		goto error;
+	}
+
+	ddf_msg(LVL_NOTE, "Allocated DMA buffer at %p virtual and %p physical.",
+	    ddisk->dma_buffer, (void *) ddisk->dma_buffer_phys);
+
+	/*
+	 * Create an exposed function.
+	 */
+	rc = ddisk_fun_create(ddisk);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed initializing ddisk controller.");
+		rc = EIO;
+		goto error;
+	}
+
+	/*
+ 	 * Register IRQ handler.
+ 	 */
+	ddisk_regs_t *res_phys = (ddisk_regs_t *) res.base;
+	ddisk_irq_pio_ranges[0].base = res.base;
+	ddisk_irq_commands[0].addr = (void *) &res_phys->status;
+	ddisk_irq_commands[3].addr = (void *) &res_phys->command;
+	rc = register_interrupt_handler(dev, ddisk->ddisk_res.irq,
+	    ddisk_irq_handler, &ddisk_irq_code);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
+		goto error;
+	}
+
+	/*
+	 * Success, report what we have found.
+	 */
+	ddf_msg(LVL_NOTE,
+	    "Device at %p with %zd blocks (%zuB) using interrupt %d",
+	    (void *) ddisk->ddisk_res.base, ddisk->blocks,
+	    ddisk->size, ddisk->ddisk_res.irq);
+
+	return EOK;
+
+error:
+	if (ddisk->ddisk_regs)
+		pio_disable(ddisk->ddisk_regs, sizeof(ddisk_regs_t));
+	if (ddisk->dma_buffer)
+		dmamem_unmap_anonymous(ddisk->dma_buffer);
+
+	return rc;
+}
+
+
+static int ddisk_dev_remove_common(ddisk_t *ddisk, bool surprise)
+{
+	int rc;
+
+	if (!surprise)
+		rc = ddisk_fun_remove(ddisk);
+	else
+		rc = ddisk_fun_unbind(ddisk);
+
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Unable to cleanup function '%s'.",
+		    DDISK_FUN_NAME);
+		return rc;
+	}
+
+	unregister_interrupt_handler(ddisk->dev, ddisk->ddisk_res.irq);
+	
+	rc = pio_disable(ddisk->ddisk_regs, sizeof(ddisk_regs_t));
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Unable to disable PIO.");
+		return rc;	
+	}
+
+	dmamem_unmap_anonymous(ddisk->dma_buffer);
+
+	return EOK;
+}
+
+static int ddisk_dev_remove(ddf_dev_t *dev)
+{
+	ddisk_t *ddisk = (ddisk_t *) ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "ddisk_dev_remove(%p)", dev);
+	return ddisk_dev_remove_common(ddisk, false);
+}
+
+static int ddisk_dev_gone(ddf_dev_t *dev)
+{
+	ddisk_t *ddisk = (ddisk_t *) ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "ddisk_dev_gone(%p)", dev);
+	return ddisk_dev_remove_common(ddisk, true);
+}
+
+static int ddisk_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "ddisk_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static int ddisk_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "ddisk_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+/** Block device connection handler */
+static void ddisk_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	ddisk_t *ddisk;
+	ddf_fun_t *fun = (ddf_fun_t *) arg;
+
+	ddisk = (ddisk_t *) ddf_dev_data_get(ddf_fun_get_dev(fun));
+	bd_conn(iid, icall, &ddisk->bds);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS MSIM ddisk device driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&ddisk_driver);
+}
Index: uspace/drv/block/ddisk/ddisk.ma
===================================================================
--- uspace/drv/block/ddisk/ddisk.ma	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/block/ddisk/ddisk.ma	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,1 @@
+10 msim/ddisk
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/bus/isa/isa.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -245,5 +245,6 @@
 	bool opened = false;
 	int fd;
-	size_t len = 0;
+	size_t len;
+	ssize_t r;
 
 	fd = open(conf_path, O_RDONLY);
@@ -269,5 +270,6 @@
 	}
 
-	if (0 >= read(fd, buf, len)) {
+	r = read_all(fd, buf, len);
+	if (r < 0) {
 		ddf_msg(LVL_ERROR, "Unable to read file '%s'.", conf_path);
 		goto cleanup;
Index: uspace/drv/platform/msim/Makefile
===================================================================
--- uspace/drv/platform/msim/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/platform/msim/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2010 Lenka Trochtova
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# - The name of the author may not be used to endorse or promote products
+#   derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = $(LIBDRV_PREFIX)/libdrv.a
+EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
+BINARY = msim
+
+SOURCES = \
+	msim.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/platform/msim/msim.c
===================================================================
--- uspace/drv/platform/msim/msim.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/platform/msim/msim.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2015 Jakub Jermar
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @defgroup msim MSIM platform driver.
+ * @brief HelenOS MSIM platform driver.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <macros.h>
+
+#include <ddi.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ipc/dev_iface.h>
+#include <ops/hw_res.h>
+#include <ops/pio_window.h>
+
+#define NAME "msim"
+
+#define MSIM_DISK_BASE	UINT32_C(0x10000200)
+#define MSIM_DISK_SIZE	UINT32_C(0x00000010)
+
+typedef struct msim_fun {
+	hw_resource_list_t hw_resources;
+	pio_window_t pio_window;
+} msim_fun_t;
+
+static int msim_dev_add(ddf_dev_t *dev);
+static void msim_init(void);
+
+/** The root device driver's standard operations. */
+static driver_ops_t msim_ops = {
+	.dev_add = &msim_dev_add
+};
+
+/** The root device driver structure. */
+static driver_t msim_driver = {
+	.name = NAME,
+	.driver_ops = &msim_ops
+};
+
+static hw_resource_t disk_regs[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = 0,
+			.size = 16,
+			.relative = true,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+	{
+		.type = INTERRUPT,
+		.res.interrupt = {
+			.irq = 6
+		}
+	}
+};
+
+static msim_fun_t disk_data = {
+	.hw_resources = {
+		sizeof(disk_regs) / sizeof(disk_regs[0]),
+		disk_regs
+	},
+	.pio_window = {
+		.mem = {
+			.base = MSIM_DISK_BASE,
+			.size = MSIM_DISK_SIZE
+		}
+	}
+};
+
+/** Obtain function soft-state from DDF function node */
+static msim_fun_t *msim_fun(ddf_fun_t *fnode)
+{
+	return ddf_fun_data_get(fnode);
+}
+
+static hw_resource_list_t *msim_get_resources(ddf_fun_t *fnode)
+{
+	msim_fun_t *fun = msim_fun(fnode);
+	
+	assert(fun != NULL);
+	return &fun->hw_resources;
+}
+
+static bool msim_enable_interrupt(ddf_fun_t *fun)
+{
+	/* Nothing to do. */
+
+	return true;
+}
+
+static pio_window_t *msim_get_pio_window(ddf_fun_t *fnode)
+{
+	msim_fun_t *fun = msim_fun(fnode);
+
+	assert(fun != NULL);
+	return &fun->pio_window;
+}
+
+static hw_res_ops_t fun_hw_res_ops = {
+	.get_resource_list = &msim_get_resources,
+	.enable_interrupt = &msim_enable_interrupt,
+};
+
+static pio_window_ops_t fun_pio_window_ops = {
+	.get_pio_window = &msim_get_pio_window
+};
+
+/* Initialized in msim_init() function. */
+static ddf_dev_ops_t msim_fun_ops;
+
+static bool
+msim_add_fun(ddf_dev_t *dev, const char *name, const char *str_match_id,
+    msim_fun_t *fun_proto)
+{
+	ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
+	
+	ddf_fun_t *fnode = NULL;
+	int rc;
+	
+	/* Create new device. */
+	fnode = ddf_fun_create(dev, fun_inner, name);
+	if (fnode == NULL)
+		goto failure;
+	
+	msim_fun_t *fun = ddf_fun_data_alloc(fnode, sizeof(msim_fun_t));
+	*fun = *fun_proto;
+	
+	/* Add match ID */
+	rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
+	if (rc != EOK)
+		goto failure;
+	
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &msim_fun_ops);
+	
+	/* Register function. */
+	if (ddf_fun_bind(fnode) != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
+		goto failure;
+	}
+	
+	return true;
+	
+failure:
+	if (fnode != NULL)
+		ddf_fun_destroy(fnode);
+	
+	ddf_msg(LVL_ERROR, "Failed adding function '%s'.", name);
+	
+	return false;
+}
+
+static bool msim_add_functions(ddf_dev_t *dev)
+{
+	return msim_add_fun(dev, "disk0", "msim/ddisk", &disk_data);
+}
+
+/** Get the root device.
+ *
+ * @param dev		The device which is root of the whole device tree (both
+ *			of HW and pseudo devices).
+ * @return		Zero on success, negative error number otherwise.
+ */
+static int msim_dev_add(ddf_dev_t *dev)
+{
+	ddf_msg(LVL_DEBUG, "msim_dev_add, device handle = %d",
+	    (int) ddf_dev_get_handle(dev));
+
+	/* Register functions. */
+	if (!msim_add_functions(dev))
+		ddf_msg(LVL_ERROR, "Failed to add functions for the MSIM platform.");
+	
+	return EOK;
+}
+
+static void msim_init(void)
+{
+	ddf_log_init(NAME);
+	msim_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
+	msim_fun_ops.interfaces[PIO_WINDOW_DEV_IFACE] = &fun_pio_window_ops;
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS MSIM platform driver\n");
+	msim_init();
+	return ddf_driver_main(&msim_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/platform/msim/msim.ma
===================================================================
--- uspace/drv/platform/msim/msim.ma	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/drv/platform/msim/msim.ma	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,1 @@
+10 platform/msim
Index: uspace/drv/time/cmos-rtc/cmos-rtc.c
===================================================================
--- uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -76,5 +76,5 @@
 	int clients_connected;
 	/** time at which the system booted */
-	time_t boottime;
+	struct timeval boot_time;
 } rtc_t;
 
@@ -97,5 +97,4 @@
 static int rtc_dev_remove(ddf_dev_t *dev);
 static void rtc_register_write(rtc_t *rtc, int reg, int data);
-static time_t uptime_get(void);
 static bool is_battery_ok(rtc_t *rtc);
 static int  rtc_fun_online(ddf_fun_t *fun);
@@ -205,5 +204,6 @@
 	ddf_msg(LVL_DEBUG, "rtc_dev_initialize %s", ddf_dev_get_name(rtc->dev));
 
-	rtc->boottime = 0;
+	rtc->boot_time.tv_sec = 0;
+	rtc->boot_time.tv_usec = 0;
 	rtc->clients_connected = 0;
 
@@ -326,14 +326,16 @@
 	fibril_mutex_lock(&rtc->mutex);
 
-	if (rtc->boottime != 0) {
+	if (rtc->boot_time.tv_sec) {
 		/* There is no need to read the current time from the
 		 * device because it has already been cached.
 		 */
 
-		time_t cur_time = rtc->boottime + uptime_get();
-
+		struct timeval curtime;
+		
+		getuptime(&curtime);
+		tv_add(&curtime, &rtc->boot_time);
 		fibril_mutex_unlock(&rtc->mutex);
 
-		return time_local2tm(cur_time, t);
+		return time_tv2tm(&curtime, t);
 	}
 
@@ -344,21 +346,25 @@
 	}
 
+	/* Microseconds are below RTC's resolution, assume 0. */
+	t->tm_usec = 0;
+
 	/* now read the registers */
 	do {
 		/* Suspend until the update process has finished */
-		while (rtc_update_in_progress(rtc));
-
-		t->tm_sec  = rtc_register_read(rtc, RTC_SEC);
-		t->tm_min  = rtc_register_read(rtc, RTC_MIN);
+		while (rtc_update_in_progress(rtc))
+			;
+
+		t->tm_sec = rtc_register_read(rtc, RTC_SEC);
+		t->tm_min = rtc_register_read(rtc, RTC_MIN);
 		t->tm_hour = rtc_register_read(rtc, RTC_HOUR);
 		t->tm_mday = rtc_register_read(rtc, RTC_DAY);
-		t->tm_mon  = rtc_register_read(rtc, RTC_MON);
+		t->tm_mon = rtc_register_read(rtc, RTC_MON);
 		t->tm_year = rtc_register_read(rtc, RTC_YEAR);
 
 		/* Now check if it is stable */
-	} while(t->tm_sec  != rtc_register_read(rtc, RTC_SEC) ||
-	    t->tm_min  != rtc_register_read(rtc, RTC_MIN) ||
+	} while(t->tm_sec != rtc_register_read(rtc, RTC_SEC) ||
+	    t->tm_min != rtc_register_read(rtc, RTC_MIN) ||
 	    t->tm_mday != rtc_register_read(rtc, RTC_DAY) ||
-	    t->tm_mon  != rtc_register_read(rtc, RTC_MON) ||
+	    t->tm_mon != rtc_register_read(rtc, RTC_MON) ||
 	    t->tm_year != rtc_register_read(rtc, RTC_YEAR));
 
@@ -366,5 +372,4 @@
 	bool _12h_mode = !(rtc_register_read(rtc, RTC_STATUS_B) &
 	    RTC_B_24H);
-
 	if (_12h_mode) {
 		/* The RTC is working in 12h mode, check if it is AM or PM */
@@ -378,11 +383,10 @@
 	/* Check if the RTC is working in BCD mode */
 	bcd_mode = !(rtc_register_read(rtc, RTC_STATUS_B) & RTC_B_BCD);
-
 	if (bcd_mode) {
-		t->tm_sec  = bcd2bin(t->tm_sec);
-		t->tm_min  = bcd2bin(t->tm_min);
+		t->tm_sec = bcd2bin(t->tm_sec);
+		t->tm_min = bcd2bin(t->tm_min);
 		t->tm_hour = bcd2bin(t->tm_hour);
 		t->tm_mday = bcd2bin(t->tm_mday);
-		t->tm_mon  = bcd2bin(t->tm_mon);
+		t->tm_mon = bcd2bin(t->tm_mon);
 		t->tm_year = bcd2bin(t->tm_year);
 	}
@@ -414,5 +418,10 @@
 		result = EINVAL;
 	else {
-		rtc->boottime = r - uptime_get();
+		struct timeval uptime;
+
+		getuptime(&uptime);
+		rtc->boot_time.tv_sec = r;
+		rtc->boot_time.tv_usec = t->tm_usec;	/* normalized */
+		tv_sub(&rtc->boot_time, &uptime);
 		result = EOK;
 	}
@@ -435,5 +444,6 @@
 	bool bcd_mode;
 	time_t norm_time;
-	time_t uptime;
+	struct timeval uptime;
+	struct timeval ntv;
 	int  reg_b;
 	int  reg_a;
@@ -445,6 +455,9 @@
 		return EINVAL;
 
-	uptime = uptime_get();
-	if (norm_time <= uptime) {
+	ntv.tv_sec = norm_time;
+	ntv.tv_usec = t->tm_usec;
+	getuptime(&uptime);
+
+	if (tv_gteq(&uptime, &ntv)) {
 		/* This is not acceptable */
 		return EINVAL;
@@ -458,6 +471,7 @@
 	}
 
-	/* boottime must be recomputed */
-	rtc->boottime = 0;
+	/* boot_time must be recomputed */
+	rtc->boot_time.tv_sec = 0;
+	rtc->boot_time.tv_usec = 0;
 
 	/* Detect the RTC epoch */
@@ -731,14 +745,4 @@
 }
 
-static time_t
-uptime_get(void)
-{
-	struct timeval tv;
-
-	getuptime(&tv);
-
-	return tv.tv_sec;
-}
-
 static int
 rtc_fun_online(ddf_fun_t *fun)
Index: uspace/lib/c/arch/ia32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ia32/Makefile.common	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/arch/ia32/Makefile.common	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -32,4 +32,5 @@
 	GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
 endif
+
 CLANG_CFLAGS += -fno-omit-frame-pointer
 
Index: uspace/lib/c/arch/ia64/include/libarch/types.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/types.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/arch/ia64/include/libarch/types.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -46,14 +46,4 @@
 #define SSIZE_MAX  INT64_MAX
 
-typedef struct {
-	uint64_t lo;
-	int64_t hi;
-} __attribute__((aligned(16))) int128_t;
-
-typedef struct {
-	uint64_t lo;
-	uint64_t hi;
-} __attribute__((aligned(16))) uint128_t;
-
 typedef uint64_t sysarg_t;
 typedef int64_t native_t;
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/generic/async.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -820,5 +820,5 @@
 	if (usecs) {
 		getuptime(&conn->wdata.to_event.expires);
-		tv_add(&conn->wdata.to_event.expires, usecs);
+		tv_add_diff(&conn->wdata.to_event.expires, usecs);
 	} else
 		conn->wdata.to_event.inlist = false;
@@ -1214,5 +1214,6 @@
 
 			} else {
-				timeout = tv_sub(&waiter->to_event.expires, &tv);
+				timeout = tv_sub_diff(&waiter->to_event.expires,
+				    &tv);
 				futex_up(&async_futex);
 			}
@@ -1505,5 +1506,5 @@
 
 	getuptime(&msg->wdata.to_event.expires);
-	tv_add(&msg->wdata.to_event.expires, timeout);
+	tv_add_diff(&msg->wdata.to_event.expires, timeout);
 	
 	/*
@@ -1587,5 +1588,5 @@
 	
 	getuptime(&msg->wdata.to_event.expires);
-	tv_add(&msg->wdata.to_event.expires, timeout);
+	tv_add_diff(&msg->wdata.to_event.expires, timeout);
 	
 	futex_down(&async_futex);
Index: uspace/lib/c/generic/fibril_synch.c
===================================================================
--- uspace/lib/c/generic/fibril_synch.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/generic/fibril_synch.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -380,5 +380,5 @@
 	if (timeout) {
 		getuptime(&wdata.to_event.expires);
-		tv_add(&wdata.to_event.expires, timeout);
+		tv_add_diff(&wdata.to_event.expires, timeout);
 		async_insert_timeout(&wdata);
 	}
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/generic/io/console.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -259,5 +259,5 @@
 	struct timeval t1;
 	gettimeofday(&t1, NULL);
-	*timeout -= tv_sub(&t1, &t0);
+	*timeout -= tv_sub_diff(&t1, &t0);
 	
 	return true;
Index: uspace/lib/c/generic/io/window.c
===================================================================
--- uspace/lib/c/generic/io/window.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/generic/io/window.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -40,8 +40,9 @@
 #include <stdio.h>
 
-int win_register(async_sess_t *sess, service_id_t *in, service_id_t *out)
+int win_register(async_sess_t *sess, window_flags_t flags, service_id_t *in,
+    service_id_t *out)
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	int ret = async_req_0_2(exch, WINDOW_REGISTER, in, out);
+	int ret = async_req_1_2(exch, WINDOW_REGISTER, flags, in, out);
 	async_exchange_end(exch);
 	
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/generic/time.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -59,4 +59,5 @@
 #define MINS_PER_HOUR  60
 #define SECS_PER_MIN   60
+#define USECS_PER_SEC  1000000
 #define MINS_PER_DAY   (MINS_PER_HOUR * HOURS_PER_DAY)
 #define SECS_PER_HOUR  (SECS_PER_MIN * MINS_PER_HOUR)
@@ -252,16 +253,17 @@
  * Optionally add specified amount of seconds.
  *
- * @param tm      Broken-down time to normalize.
- * @param sec_add Seconds to add.
+ * @param tm Broken-down time to normalize.
+ * @param tv Timeval to add.
  *
  * @return 0 on success, -1 on overflow
  *
  */
-static int normalize_time(struct tm *tm, time_t sec_add)
+static int normalize_tm_tv(struct tm *tm, const struct timeval *tv)
 {
 	// TODO: DST correction
 	
 	/* Set initial values. */
-	time_t sec = tm->tm_sec + sec_add;
+	time_t usec = tm->tm_usec + tv->tv_usec;
+	time_t sec = tm->tm_sec + tv->tv_sec;
 	time_t min = tm->tm_min;
 	time_t hour = tm->tm_hour;
@@ -271,4 +273,6 @@
 	
 	/* Adjust time. */
+	sec += floor_div(usec, USECS_PER_SEC);
+	usec = floor_mod(usec, USECS_PER_SEC);
 	min += floor_div(sec, SECS_PER_MIN);
 	sec = floor_mod(sec, SECS_PER_MIN);
@@ -319,4 +323,5 @@
 	
 	/* And put the values back to the struct. */
+	tm->tm_usec = (int) usec;
 	tm->tm_sec = (int) sec;
 	tm->tm_min = (int) min;
@@ -335,4 +340,15 @@
 }
 
+static int normalize_tm_time(struct tm *tm, time_t time)
+{
+	struct timeval tv = {
+		.tv_sec = time,
+		.tv_usec = 0
+	};
+
+	return normalize_tm_tv(tm, &tv);
+}
+
+
 /** Which day the week-based year starts on.
  *
@@ -442,4 +458,16 @@
 }
 
+static void tv_normalize(struct timeval *tv)
+{
+	while (tv->tv_usec > USECS_PER_SEC) {
+		tv->tv_sec++;
+		tv->tv_usec -= USECS_PER_SEC;
+	}
+	while (tv->tv_usec < 0) {
+		tv->tv_sec--;
+		tv->tv_usec += USECS_PER_SEC;
+	}
+}
+
 /** Add microseconds to given timeval.
  *
@@ -448,19 +476,27 @@
  *
  */
-void tv_add(struct timeval *tv, suseconds_t usecs)
-{
-	tv->tv_sec += usecs / 1000000;
-	tv->tv_usec += usecs % 1000000;
-	
-	if (tv->tv_usec > 1000000) {
-		tv->tv_sec++;
-		tv->tv_usec -= 1000000;
-	}
-}
-
-/** Subtract two timevals.
+void tv_add_diff(struct timeval *tv, suseconds_t usecs)
+{
+	tv->tv_sec += usecs / USECS_PER_SEC;
+	tv->tv_usec += usecs % USECS_PER_SEC;
+	tv_normalize(tv);
+}
+
+/** Add two timevals.
  *
  * @param tv1 First timeval.
  * @param tv2 Second timeval.
+ */
+void tv_add(struct timeval *tv1, struct timeval *tv2)
+{
+	tv1->tv_sec += tv2->tv_sec;
+	tv1->tv_usec += tv2->tv_usec;
+	tv_normalize(tv1);
+}
+
+/** Subtract two timevals.
+ *
+ * @param tv1 First timeval.
+ * @param tv2 Second timeval.
  *
  * @return Difference between tv1 and tv2 (tv1 - tv2) in
@@ -468,8 +504,21 @@
  *
  */
-suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
+suseconds_t tv_sub_diff(struct timeval *tv1, struct timeval *tv2)
 {
 	return (tv1->tv_usec - tv2->tv_usec) +
-	    ((tv1->tv_sec - tv2->tv_sec) * 1000000);
+	    ((tv1->tv_sec - tv2->tv_sec) * USECS_PER_SEC);
+}
+
+/** Subtract two timevals.
+ *
+ * @param tv1 First timeval.
+ * @param tv2 Second timeval.
+ *
+ */
+void tv_sub(struct timeval *tv1, struct timeval *tv2)
+{
+	tv1->tv_sec -= tv2->tv_sec;
+	tv1->tv_usec -= tv2->tv_usec;
+	tv_normalize(tv1);
 }
 
@@ -573,5 +622,5 @@
 		goto fallback;
 	
-	tv->tv_usec = 0;
+	tv->tv_usec = time.tm_usec;
 	tv->tv_sec = mktime(&time);
 	
@@ -689,5 +738,5 @@
 	// TODO: detect overflow
 	
-	normalize_time(tm, 0);
+	normalize_tm_time(tm, 0);
 	return secs_since_epoch(tm);
 }
@@ -944,4 +993,5 @@
 	
 	/* Set result to epoch. */
+	result->tm_usec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -951,5 +1001,5 @@
 	result->tm_year = 70; /* 1970 */
 	
-	if (normalize_time(result, time) == -1)
+	if (normalize_tm_time(result, time) == -1)
 		return EOVERFLOW;
 	
@@ -1014,5 +1064,5 @@
  * Time is expressed relative to the user's specified timezone.
  *
- * @param timer  Time to convert.
+ * @param tv     Timeval to convert.
  * @param result Structure to store the result to.
  *
@@ -1020,5 +1070,5 @@
  *
  */
-int time_local2tm(const time_t time, struct tm *restrict result)
+int time_tv2tm(const struct timeval *tv, struct tm *restrict result)
 {
 	// TODO: Deal with timezones.
@@ -1026,4 +1076,5 @@
 	
 	/* Set result to epoch. */
+	result->tm_usec = 0;
 	result->tm_sec = 0;
 	result->tm_min = 0;
@@ -1033,8 +1084,28 @@
 	result->tm_year = 70; /* 1970 */
 	
-	if (normalize_time(result, time) == -1)
+	if (normalize_tm_tv(result, tv) == -1)
 		return EOVERFLOW;
 	
 	return EOK;
+}
+
+/** Converts a time value to a broken-down local time.
+ *
+ * Time is expressed relative to the user's specified timezone.
+ *
+ * @param timer  Time to convert.
+ * @param result Structure to store the result to.
+ *
+ * @return EOK on success or a negative error code.
+ *
+ */
+int time_local2tm(const time_t time, struct tm *restrict result)
+{
+	struct timeval tv = {
+		.tv_sec = time,
+		.tv_usec = 0
+	};
+
+	return time_tv2tm(&tv, result);
 }
 
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/include/io/window.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -42,4 +42,10 @@
 #include <io/kbd_event.h>
 #include <io/pos_event.h>
+
+typedef enum {
+	WINDOW_MAIN = 1,
+	WINDOW_DECORATED = 2,
+	WINDOW_RESIZEABLE = 4
+} window_flags_t;
 
 typedef enum {
@@ -108,5 +114,6 @@
 } window_event_t;
 
-extern int win_register(async_sess_t *, service_id_t *, service_id_t *);
+extern int win_register(async_sess_t *, window_flags_t, service_id_t *,
+    service_id_t *);
 
 extern int win_get_event(async_sess_t *, window_event_t *);
Index: uspace/lib/c/include/sys/time.h
===================================================================
--- uspace/lib/c/include/sys/time.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/c/include/sys/time.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -50,4 +50,5 @@
 
 struct tm {
+	int tm_usec;   /* Microseconds [0,999999]. */
 	int tm_sec;    /* Seconds [0,60]. */
 	int tm_min;    /* Minutes [0,59]. */
@@ -71,6 +72,8 @@
 };
 
-extern void tv_add(struct timeval *, suseconds_t);
-extern suseconds_t tv_sub(struct timeval *, struct timeval *);
+extern void tv_add_diff(struct timeval *, suseconds_t);
+extern void tv_add(struct timeval *, struct timeval *);
+extern suseconds_t tv_sub_diff(struct timeval *, struct timeval *);
+extern void tv_sub(struct timeval *, struct timeval *);
 extern int tv_gt(struct timeval *, struct timeval *);
 extern int tv_gteq(struct timeval *, struct timeval *);
@@ -85,4 +88,5 @@
 extern int time_utc2str(const time_t, char *);
 extern void time_tm2str(const struct tm *, char *);
+extern int time_tv2tm(const struct timeval *, struct tm *);
 extern int time_local2tm(const time_t, struct tm *);
 extern int time_local2str(const time_t, char *);
Index: uspace/lib/crypto/crypto.c
===================================================================
--- uspace/lib/crypto/crypto.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/crypto/crypto.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -54,7 +54,4 @@
 	(uint32_t)((val) - 1) : (uint32_t)(val))
 
-/* Left rotation for UINT32. */
-#define rotl_uint32(val, shift) (((val) << shift) | ((val) >> (32 - shift)))
-
 /* Pick value at specified index from array or zero if out of bounds. */
 #define get_at(input, size, i) (i < size ? input[i] : 0)
@@ -290,5 +287,5 @@
 	}
 	
-	uint8_t temp_work[HMAC_BLOCK_LENGTH + msg_size];
+	uint8_t temp_work[HMAC_BLOCK_LENGTH + max(msg_size, hash_sel)];
 	memcpy(temp_work, i_key_pad, HMAC_BLOCK_LENGTH);
 	memcpy(temp_work + HMAC_BLOCK_LENGTH, msg, msg_size);
@@ -328,5 +325,5 @@
 		return ENOMEM;
 	
-	uint8_t work_salt[salt_size + sizeof(uint32_t)];
+	uint8_t work_salt[salt_size + 4];
 	memcpy(work_salt, salt, salt_size);
 	uint8_t work_hmac[HASH_SHA1];
@@ -336,9 +333,10 @@
 	
 	for(size_t i = 0; i < 2; i++) {
-		uint32_t big_i = host2uint32_t_be(i+1);
-		memcpy(work_salt + salt_size, &big_i, sizeof(uint32_t));
-		hmac(pass, pass_size, work_salt, salt_size + sizeof(uint32_t),
+		uint32_t be_i = host2uint32_t_be(i+1);
+		memcpy(work_salt + salt_size, &be_i, 4);
+		hmac(pass, pass_size, work_salt, salt_size + 4,
 			work_hmac, HASH_SHA1);
 		memcpy(xor_hmac, work_hmac, HASH_SHA1);
+		
 		for(size_t k = 1; k < 4096; k++) {
 			memcpy(temp_hmac, work_hmac, HASH_SHA1);
Index: uspace/lib/crypto/crypto.h
===================================================================
--- uspace/lib/crypto/crypto.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/crypto/crypto.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -35,4 +35,10 @@
 #define PBKDF2_KEY_LENGTH 32
 
+/* Left rotation for UINT32. */
+#define rotl_uint32(val, shift) (((val) << shift) | ((val) >> (32 - shift)))
+
+/* Right rotation for UINT32. */
+#define rotr_uint32(val, shift) (((val) >> shift) | ((val) << (32 - shift)))
+
 /** Hash function selector and also result hash length indicator. */
 typedef enum {
Index: uspace/lib/crypto/rc4.c
===================================================================
--- uspace/lib/crypto/rc4.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/crypto/rc4.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -104,5 +104,5 @@
 	uint8_t i = 0, j = 0;
 	for(size_t k = 0; k < skip; k++) {
-		i = i+1;
+		i = i + 1;
 		j = j + sbox[i];
 		swap(i, j, sbox);
@@ -112,5 +112,5 @@
 	uint8_t val;
 	for(size_t k = 0; k < input_size; k++) {
-		i = i+1;
+		i = i + 1;
 		j = j + sbox[i];
 		swap(i, j, sbox);
Index: uspace/lib/ext4/libext4_directory.c
===================================================================
--- uspace/lib/ext4/libext4_directory.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ext4/libext4_directory.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -390,13 +390,9 @@
 	    (ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX))) {
 		int rc = ext4_directory_dx_add_entry(parent, child, name);
-		
+
 		/* Check if index is not corrupted */
-		if (rc != EXT4_ERR_BAD_DX_DIR) {
-			if (rc != EOK)
-				return rc;
-			
-			return EOK;
-		}
-		
+		if (rc != EXT4_ERR_BAD_DX_DIR)
+			return rc;
+
 		/* Needed to clear dir index flag if corrupted */
 		ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX);
Index: uspace/lib/ext4/libext4_extent.c
===================================================================
--- uspace/lib/ext4/libext4_extent.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ext4/libext4_extent.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -797,4 +797,5 @@
 			if (rc != EOK) {
 				ext4_balloc_free_block(inode_ref, fblock);
+				block_put(block);
 				return rc;
 			}
Index: uspace/lib/ext4/libext4_filesystem.c
===================================================================
--- uspace/lib/ext4/libext4_filesystem.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ext4/libext4_filesystem.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -53,33 +53,30 @@
     enum cache_mode cmode)
 {
+	ext4_superblock_t *temp_superblock = NULL;
+
 	fs->device = service_id;
-	
+
 	/* Initialize block library (4096 is size of communication channel) */
 	int rc = block_init(EXCHANGE_SERIALIZE, fs->device, 4096);
 	if (rc != EOK)
-		return rc;
-	
+		goto err;
+
 	/* Read superblock from device to memory */
-	ext4_superblock_t *temp_superblock;
 	rc = ext4_superblock_read_direct(fs->device, &temp_superblock);
-	if (rc != EOK) {
-		block_fini(fs->device);
-		return rc;
-	}
-	
+	if (rc != EOK)
+		goto err_1;
+
 	/* Read block size from superblock and check */
 	uint32_t block_size = ext4_superblock_get_block_size(temp_superblock);
 	if (block_size > EXT4_MAX_BLOCK_SIZE) {
-		block_fini(fs->device);
-		return ENOTSUP;
-	}
-	
+		rc = ENOTSUP;
+		goto err_1;
+	}
+
 	/* Initialize block caching by libblock */
 	rc = block_cache_init(service_id, block_size, 0, cmode);
-	if (rc != EOK) {
-		block_fini(fs->device);
-		return rc;
-	}
-	
+	if (rc != EOK)
+		goto err_1;
+
 	/* Compute limits for indirect block levels */
 	uint32_t block_ids_per_block = block_size / sizeof(uint32_t);
@@ -92,32 +89,37 @@
 		    fs->inode_blocks_per_level[i];
 	}
-	
+
 	/* Return loaded superblock */
 	fs->superblock = temp_superblock;
-	
+
 	uint16_t state = ext4_superblock_get_state(fs->superblock);
-	
+
 	if (((state & EXT4_SUPERBLOCK_STATE_VALID_FS) !=
 	    EXT4_SUPERBLOCK_STATE_VALID_FS) ||
 	    ((state & EXT4_SUPERBLOCK_STATE_ERROR_FS) ==
 	    EXT4_SUPERBLOCK_STATE_ERROR_FS)) {
-		block_cache_fini(fs->device);
-		block_fini(fs->device);
-		return ENOTSUP;
-	}
-	
+		rc = ENOTSUP;
+		goto err_2;
+	}
+
 	/* Mark system as mounted */
 	ext4_superblock_set_state(fs->superblock, EXT4_SUPERBLOCK_STATE_ERROR_FS);
 	rc = ext4_superblock_write_direct(fs->device, fs->superblock);
-	if (rc != EOK) {
-		block_cache_fini(fs->device);
-		block_fini(fs->device);
-		return rc;
-	}
-	
+	if (rc != EOK)
+		goto err_2;
+
 	uint16_t mnt_count = ext4_superblock_get_mount_count(fs->superblock);
 	ext4_superblock_set_mount_count(fs->superblock, mnt_count + 1);
-	
+
 	return EOK;
+
+err_2:
+	block_cache_fini(fs->device);
+err_1:
+	block_fini(fs->device);
+err:
+	if (temp_superblock)
+		ext4_superblock_release(temp_superblock);
+	return rc;
 }
 
@@ -845,6 +847,8 @@
 				
 				rc = block_put(subblock);
-				if (rc != EOK)
+				if (rc != EOK) {
+					block_put(block);
 					return rc;
+				}
 			}
 			
Index: uspace/lib/ext4/libext4_superblock.c
===================================================================
--- uspace/lib/ext4/libext4_superblock.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ext4/libext4_superblock.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -1178,4 +1178,14 @@
 }
 
+/** Release the memory allocated for the superblock structure
+ *
+ * @param sb         Superblock to be freed
+ *
+ */
+void ext4_superblock_release(ext4_superblock_t *sb)
+{
+	free(sb);
+}
+
 /** Check sanity of the superblock.
  *
Index: uspace/lib/ext4/libext4_superblock.h
===================================================================
--- uspace/lib/ext4/libext4_superblock.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ext4/libext4_superblock.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -145,4 +145,5 @@
 extern int ext4_superblock_read_direct(service_id_t, ext4_superblock_t **);
 extern int ext4_superblock_write_direct(service_id_t, ext4_superblock_t *);
+extern void ext4_superblock_release(ext4_superblock_t *);
 extern int ext4_superblock_check_sanity(ext4_superblock_t *);
 
Index: uspace/lib/gui/window.c
===================================================================
--- uspace/lib/gui/window.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/gui/window.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -591,5 +591,5 @@
 }
 
-window_t *window_open(const char *winreg, bool is_main, bool is_decorated,
+window_t *window_open(const char *winreg, window_flags_t flags,
     const char *caption)
 {
@@ -598,6 +598,6 @@
 		return NULL;
 	
-	win->is_main = is_main;
-	win->is_decorated = is_decorated;
+	win->is_main = flags & WINDOW_MAIN;
+	win->is_decorated = flags & WINDOW_DECORATED;
 	win->is_focused = true;
 	prodcons_initialize(&win->events);
@@ -632,5 +632,5 @@
 	service_id_t in_dsid;
 	service_id_t out_dsid;
-	rc = win_register(reg_sess, &in_dsid, &out_dsid);
+	rc = win_register(reg_sess, flags, &in_dsid, &out_dsid);
 	async_hangup(reg_sess);
 	if (rc != EOK) {
Index: uspace/lib/gui/window.h
===================================================================
--- uspace/lib/gui/window.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/gui/window.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -65,6 +65,7 @@
  * Allocate all resources for new window and register it in the compositor.
  * If the window is declared as main, its closure causes termination of the
- * whole application. Note that opened window does not have any surface yet. */
-extern window_t *window_open(const char *, bool, bool, const char *);
+ * whole application. Note that opened window does not have any surface yet.
+ */
+extern window_t *window_open(const char *, window_flags_t, const char *);
 
 /**
Index: uspace/lib/ieee80211/include/ieee80211_impl.h
===================================================================
--- uspace/lib/ieee80211/include/ieee80211_impl.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ieee80211/include/ieee80211_impl.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -58,4 +58,10 @@
 extern int ieee80211_aes_key_unwrap(uint8_t *kek, uint8_t *data, 
 	size_t data_size, uint8_t *output);
+extern int ieee80211_michael_mic(uint8_t *key, uint8_t *data, size_t data_size, 
+	uint8_t *mic);
+extern uint16_t uint16le_from_seq(void *seq);
+extern uint32_t uint32le_from_seq(void *seq);
+extern uint16_t uint16be_from_seq(void *seq);
+extern uint32_t uint32be_from_seq(void *seq);
 extern int rnd_sequence(uint8_t *sequence, size_t length);
 extern uint8_t *min_sequence(uint8_t *seq1, uint8_t *seq2, size_t size);
Index: uspace/lib/ieee80211/include/ieee80211_private.h
===================================================================
--- uspace/lib/ieee80211/include/ieee80211_private.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ieee80211/include/ieee80211_private.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -87,4 +87,7 @@
 #define TK_OFFSET 32
 
+/* Length of Michael MIC code used in TKIP security suite. */
+#define MIC_LENGTH 8
+
 /* 
  * Length of data to be encrypted by PRF function:
@@ -98,10 +101,4 @@
 	IEEE80211_CCMP_HEADER_LENGTH = 8
 } ieee80211_encrypt_header_reserve_length_t;
-
-/* Special room in footer reserved for encryption. */
-typedef enum {
-	IEEE80211_TKIP_FOOTER_LENGTH = 4,
-	IEEE80211_CCMP_FOOTER_LENGTH = 8
-} ieee80211_encrypt_footer_reserve_length_t;
 
 /** IEEE 802.11 PTK key length. */
@@ -405,4 +402,6 @@
 }
 
+extern bool ieee80211_is_fromds_frame(uint16_t frame_ctrl);
+extern bool ieee80211_is_tods_frame(uint16_t frame_ctrl);
 extern void ieee80211_set_connect_request(ieee80211_dev_t *ieee80211_dev);
 extern bool ieee80211_pending_connect_request(ieee80211_dev_t *ieee80211_dev);
Index: uspace/lib/ieee80211/src/ieee80211.c
===================================================================
--- uspace/lib/ieee80211/src/ieee80211.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ieee80211/src/ieee80211.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -160,5 +160,5 @@
  * @return True if it is TODS frame, otherwise false.
  */
-static inline bool ieee80211_is_tods_frame(uint16_t frame_ctrl)
+inline bool ieee80211_is_tods_frame(uint16_t frame_ctrl)
 {
 	frame_ctrl = uint16_t_le2host(frame_ctrl);
@@ -174,5 +174,5 @@
  * @return True if it is FROMDS frame, otherwise false.
  */
-static inline bool ieee80211_is_fromds_frame(uint16_t frame_ctrl)
+inline bool ieee80211_is_fromds_frame(uint16_t frame_ctrl)
 {
 	frame_ctrl = uint16_t_le2host(frame_ctrl);
@@ -207,5 +207,5 @@
 	frame_ctrl = uint16_t_le2host(frame_ctrl);
 	
-	return (frame_ctrl & IEEE80211_FRAME_CTRL_PROTECTED) != 0;
+	return (frame_ctrl & IEEE80211_FRAME_CTRL_PROTECTED);
 }
 
@@ -572,8 +572,9 @@
 	
 	/* Init crypto data. */
-	size_t add_size = 0;
+	bool add_mic = false;
+	size_t head_space = 0, mic_space = 0;
 	uint16_t crypto = 0;
-	uint8_t add_data[8];
-	memset(add_data, 0, 8);
+	uint8_t head_data[head_space];
+	memset(head_data, 0, head_space);
 	
 	// TODO: Distinguish used key (pair/group) by dest address ?
@@ -582,10 +583,11 @@
 		switch(sec_suite) {
 			case IEEE80211_SECURITY_SUITE_TKIP:
-				add_size = IEEE80211_TKIP_HEADER_LENGTH;
-				// TODO: Add data?
+				head_space = IEEE80211_TKIP_HEADER_LENGTH;
+				mic_space = MIC_LENGTH;
+				add_mic = true;
 				break;
 			case IEEE80211_SECURITY_SUITE_CCMP:
-				add_size = IEEE80211_CCMP_HEADER_LENGTH;
-				add_data[3] = 0x20;
+				head_space = IEEE80211_CCMP_HEADER_LENGTH;
+				head_data[3] = 0x20;
 				break;
 			default:
@@ -596,15 +598,15 @@
 	}
 	
-	complete_size += add_size;
+	complete_size += head_space + mic_space;
 	
 	void *complete_buffer = malloc(complete_size);
 	memset(complete_buffer, 0, complete_size);
 	
-	if(add_size) {
+	if(head_space) {
 		memcpy(complete_buffer + sizeof(ieee80211_data_header_t),
-			add_data, add_size);
-	}
-	
-	memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + add_size,
+			head_data, head_space);
+	}
+	
+	memcpy(complete_buffer + sizeof(ieee80211_data_header_t) + head_space,
 		rfc1042_header,
 		ARRAY_SIZE(rfc1042_header));
@@ -612,5 +614,5 @@
 	memcpy(complete_buffer + 
 		sizeof(ieee80211_data_header_t) +
-		ARRAY_SIZE(rfc1042_header) + add_size, 
+		ARRAY_SIZE(rfc1042_header) + head_space, 
 		data + drop_bytes, size - drop_bytes);
 	
@@ -628,4 +630,13 @@
 	memcpy(data_header->address2, data + ETH_ADDR, ETH_ADDR);
 	memcpy(data_header->address3, data, ETH_ADDR);
+	
+	if(add_mic) {
+		size_t size_wo_mic = complete_size - MIC_LENGTH;
+		uint8_t *tx_mic = ieee80211_dev->bssid_info.ptk +
+			TK_OFFSET +
+			IEEE80211_TKIP_TX_MIC_OFFSET;
+		ieee80211_michael_mic(tx_mic, complete_buffer, size_wo_mic,
+			complete_buffer + size_wo_mic);
+	}
 	
 	ieee80211_dev->ops->tx_handler(ieee80211_dev, 
@@ -1151,9 +1162,4 @@
 			ap_data->scan_result.security.auth = -1;
 	}
-}
-
-static uint32_t uint32_from_uint8_seq(uint8_t *seq)
-{
-	return (*seq << 24) + (*(seq+1) << 16) + (*(seq+2) << 8) + *(seq+3); 
 }
 
@@ -1191,5 +1197,5 @@
 				break;
 			case IEEE80211_VENDOR_IE:
-				if(uint32_from_uint8_seq(it + 
+				if(uint32be_from_seq(it + 
 					sizeof(ieee80211_ie_header_t)) ==
 					WPA_OUI) {
@@ -1206,5 +1212,5 @@
 						sizeof(uint32_t));
 					copy_auth_ie(ie_header, ap_data, it);
-				} else if(uint32_from_uint8_seq(it + 
+				} else if(uint32be_from_seq(it + 
 					sizeof(ieee80211_ie_header_t)) ==
 					GTK_OUI) {
Index: uspace/lib/ieee80211/src/ieee80211_impl.c
===================================================================
--- uspace/lib/ieee80211/src/ieee80211_impl.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/ieee80211/src/ieee80211_impl.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -265,4 +265,105 @@
 }
 
+static void ieee80211_michael_mic_block(uint32_t *l, uint32_t *r, 
+	uint32_t value)
+{
+	*l ^= value;
+	*r ^= rotl_uint32(*l, 17);
+	*l += *r;
+	*r ^= ((*l & 0x00FF00FF) << 8) | ((*l & 0xFF00FF00) >> 8);
+	*l += *r;
+	*r ^= rotl_uint32(*l, 3);
+	*l += *r;
+	*r ^= rotr_uint32(*l, 2);
+	*l += *r;
+}
+
+int ieee80211_michael_mic(uint8_t *key, uint8_t *buffer, size_t size, 
+	uint8_t *mic)
+{
+	if(!key || !buffer)
+		return EINVAL;
+	
+	if(!mic)
+		return ENOMEM;
+	
+	uint32_t l = uint32le_from_seq(key);
+	uint32_t r = uint32le_from_seq(key + 4);
+	
+	ieee80211_data_header_t *data_header =
+		(ieee80211_data_header_t *) buffer;
+	
+	uint8_t *data = buffer + sizeof(ieee80211_data_header_t) + 
+		IEEE80211_TKIP_HEADER_LENGTH;
+	size_t data_size = size - sizeof(ieee80211_data_header_t) -
+		IEEE80211_TKIP_HEADER_LENGTH;
+	
+	/* Process header. */
+	uint8_t *src_addr = 
+		ieee80211_is_fromds_frame(data_header->frame_ctrl) ?
+			data_header->address3 : data_header->address2;
+	uint8_t *dest_addr = 
+		ieee80211_is_tods_frame(data_header->frame_ctrl) ?
+			data_header->address3 : data_header->address1;
+	
+	ieee80211_michael_mic_block(&l, &r, uint32le_from_seq(dest_addr));
+	ieee80211_michael_mic_block(&l, &r, 
+		uint16le_from_seq(dest_addr + 4) |
+		(uint16le_from_seq(src_addr) << 16));
+	ieee80211_michael_mic_block(&l, &r, uint32le_from_seq(src_addr + 2));
+	ieee80211_michael_mic_block(&l, &r, 0);
+	
+	/* Process data. */
+	size_t blocks = data_size / 4;
+	size_t pad = data_size % 4;
+	
+	for(size_t k = 0; k < blocks; k++) {
+		ieee80211_michael_mic_block(&l, &r, 
+			uint32le_from_seq(&data[k*4]));
+	}
+	
+	/* Add padding. */
+	uint32_t value = 0x5A;
+	for(size_t i = pad; i > 0; i--) {
+		value <<= 8;
+		value |= data[blocks*4 + (i-1)];
+	}
+	
+	ieee80211_michael_mic_block(&l, &r, value);
+	ieee80211_michael_mic_block(&l, &r, 0);
+	
+	l = host2uint32_t_le(l);
+	r = host2uint32_t_le(r);
+	
+	memcpy(mic, &l, 4);
+	memcpy(mic + 4, &r, 4);
+	
+	return EOK;
+}
+
+uint16_t uint16le_from_seq(void *seq)
+{
+	uint16_t *u16 = (uint16_t *) seq;
+	return uint16_t_le2host(*u16); 
+}
+
+uint32_t uint32le_from_seq(void *seq)
+{
+	uint32_t *u32 = (uint32_t *) seq;
+	return uint32_t_le2host(*u32); 
+}
+
+uint16_t uint16be_from_seq(void *seq)
+{
+	uint16_t *u16 = (uint16_t *) seq;
+	return uint16_t_be2host(*u16); 
+}
+
+uint32_t uint32be_from_seq(void *seq)
+{
+	uint32_t *u32 = (uint32_t *) seq;
+	return uint32_t_be2host(*u32); 
+}
+
 int rnd_sequence(uint8_t *sequence, size_t length)
 {
Index: uspace/lib/math/arch/abs32le/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/abs32le/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/abs32le/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/amd64/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/amd64/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/amd64/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,14 +36,15 @@
 #define LIBMATH_amd64_MATH_H_
 
+#include <mathtypes.h>
 #include <mod.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-extern double sin(double);
-extern double cos(double);
-extern double trunc(double);
+extern float64_t sin(float64_t);
+extern float64_t cos(float64_t);
+extern float64_t trunc(float64_t);
 
 #endif
Index: uspace/lib/math/arch/arm32/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/arm32/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/arm32/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/ia32/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/ia32/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/ia32/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,14 +36,15 @@
 #define LIBMATH_ia32_MATH_H_
 
+#include <mathtypes.h>
 #include <mod.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-extern double sin(double);
-extern double cos(double);
-extern double trunc(double);
+extern float64_t sin(float64_t);
+extern float64_t cos(float64_t);
+extern float64_t trunc(float64_t);
 
 #endif
Index: uspace/lib/math/arch/ia64/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/ia64/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/ia64/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/mips32/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/mips32/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/mips32/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/mips32eb/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/mips32eb/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/mips32eb/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/ppc32/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/ppc32/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/ppc32/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
 static inline double trunc(double val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/sparc32/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/sparc32/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/sparc32/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/arch/sparc64/include/libarch/math.h
===================================================================
--- uspace/lib/math/arch/sparc64/include/libarch/math.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/arch/sparc64/include/libarch/math.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -41,15 +41,15 @@
 #include <trig.h>
 
-static inline double fmod(double dividend, double divisor)
+static inline float64_t fmod(float64_t dividend, float64_t divisor)
 {
-	return double_mod(dividend, divisor);
+	return float64_mod(dividend, divisor);
 }
 
-static inline double trunc(double val)
+static inline float64_t trunc(float64_t val)
 {
-	double_t arg;
+	float64_u arg;
 	arg.val = val;
 	
-	double_t ret;
+	float64_u ret;
 	ret.data = trunc_float64(arg.data);
 	
@@ -57,12 +57,12 @@
 }
 
-static inline double sin(double val)
+static inline float64_t sin(float64_t val)
 {
-	return double_sin(val);
+	return float64_sin(val);
 }
 
-static inline double cos(double val)
+static inline float64_t cos(float64_t val)
 {
-	return double_cos(val);
+	return float64_cos(val);
 }
 
Index: uspace/lib/math/generic/mod.c
===================================================================
--- uspace/lib/math/generic/mod.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/generic/mod.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -52,9 +52,9 @@
  *
  */
-double double_mod(double dividend, double divisor)
+float64_t float64_mod(float64_t dividend, float64_t divisor)
 {
 	// FIXME: replace with exact arithmetics
 	
-	double quotient = trunc(dividend / divisor);
+	float64_t quotient = trunc(dividend / divisor);
 	
 	return (dividend - quotient * divisor);
Index: uspace/lib/math/generic/trig.c
===================================================================
--- uspace/lib/math/generic/trig.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/generic/trig.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -39,5 +39,5 @@
 
 /** Precomputed values for factorial (starting from 1!) */
-static double factorials[TAYLOR_DEGREE] = {
+static float64_t factorials[TAYLOR_DEGREE] = {
 	1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800,
 	479001600, 6227020800
@@ -56,8 +56,8 @@
  *
  */
-static double taylor_sin(double arg)
-{
-	double ret = 0;
-	double nom = 1;
+static float64_t taylor_sin(float64_t arg)
+{
+	float64_t ret = 0;
+	float64_t nom = 1;
 	
 	for (unsigned int i = 0; i < TAYLOR_DEGREE; i++) {
@@ -85,8 +85,8 @@
  *
  */
-static double taylor_cos(double arg)
-{
-	double ret = 1;
-	double nom = 1;
+static float64_t taylor_cos(float64_t arg)
+{
+	float64_t ret = 1;
+	float64_t nom = 1;
 	
 	for (unsigned int i = 0; i < TAYLOR_DEGREE; i++) {
@@ -114,5 +114,5 @@
  *
  */
-static double base_sin(double arg)
+static float64_t base_sin(float64_t arg)
 {
 	unsigned int period = arg / (M_PI / 4);
@@ -147,5 +147,5 @@
  *
  */
-static double base_cos(double arg)
+static float64_t base_cos(float64_t arg)
 {
 	unsigned int period = arg / (M_PI / 4);
@@ -156,5 +156,5 @@
 	case 1:
 	case 2:
-		return taylor_sin(arg - M_PI / 2);
+		return -taylor_sin(arg - M_PI / 2);
 	case 3:
 	case 4:
@@ -162,5 +162,5 @@
 	case 5:
 	case 6:
-		return -taylor_sin(arg - 3 * M_PI / 2);
+		return taylor_sin(arg - 3 * M_PI / 2);
 	default:
 		return taylor_cos(arg - 2 * M_PI);
@@ -177,7 +177,7 @@
  *
  */
-double double_sin(double arg)
-{
-	double base_arg = fmod(arg, 2 * M_PI);
+float64_t float64_sin(float64_t arg)
+{
+	float64_t base_arg = fmod(arg, 2 * M_PI);
 	
 	if (base_arg < 0)
@@ -196,7 +196,7 @@
  *
  */
-double double_cos(double arg)
-{
-	double base_arg = fmod(arg, 2 * M_PI);
+float64_t float64_cos(float64_t arg)
+{
+	float64_t base_arg = fmod(arg, 2 * M_PI);
 	
 	if (base_arg < 0)
Index: uspace/lib/math/include/mathtypes.h
===================================================================
--- uspace/lib/math/include/mathtypes.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/include/mathtypes.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -191,51 +191,121 @@
 #endif
 
-typedef union {
-	float val;
-	
+
 #if defined(FLOAT_SIZE_32)
+
+#ifndef float32_t
+	#define float32_t  float
+#endif
+
+#elif defined(FLOAT_SIZE_64)
+
+#ifndef float64_t
+	#define float64_t  float
+#endif
+
+#elif defined(FLOAT_SIZE_96)
+
+#ifndef float96_t
+	#define float96_t  float
+#endif
+
+#elif defined(FLOAT_SIZE_128)
+
+#ifndef float128_t
+	#define float128_t  float
+#endif
+
+#endif
+
+
+#if defined(DOUBLE_SIZE_32)
+
+#ifndef float32_t
+	#define float32_t  double
+#endif
+
+#elif defined(DOUBLE_SIZE_64)
+
+#ifndef float64_t
+	#define float64_t  double
+#endif
+
+#elif defined(DOUBLE_SIZE_96)
+
+#ifndef float96_t
+	#define float96_t  double
+#endif
+
+#elif defined(DOUBLE_SIZE_128)
+
+#ifndef float128_t
+	#define float128_t  double
+#endif
+
+#endif
+
+
+#if defined(LONG_DOUBLE_SIZE_32)
+
+#ifndef float32_t
+	#define float32_t  long double
+#endif
+
+#elif defined(LONG_DOUBLE_SIZE_64)
+
+#ifndef float64_t
+	#define float64_t  long double
+#endif
+
+#elif defined(LONG_DOUBLE_SIZE_96)
+
+#ifndef float96_t
+	#define float96_t  long double
+#endif
+
+#elif defined(LONG_DOUBLE_SIZE_128)
+
+#ifndef float128_t
+	#define float128_t  long double
+#endif
+
+#endif
+
+
+#ifdef float32_t
+
+typedef union {
+	float32_t val;
 	float32 data;
-#elif defined(FLOAT_SIZE_64)
+} float32_u;
+
+#endif
+
+#ifdef float64_t
+
+typedef union {
+	float64_t val;
 	float64 data;
-#elif defined(FLOAT_SIZE_96)
+} float64_u;
+
+#endif
+
+#ifdef float96_t
+
+typedef union {
+	float96_t val;
 	float96 data;
-#elif defined(FLOAT_SIZE_128)
+} float96_u;
+
+#endif
+
+#ifdef float128_t
+
+typedef union {
+	float128_t val;
 	float128 data;
-#else
-	#error Unsupported float size
-#endif
-} float_t;
-
-typedef union {
-	double val;
-	
-#if defined(DOUBLE_SIZE_32)
-	float32 data;
-#elif defined(DOUBLE_SIZE_64)
-	float64 data;
-#elif defined(DOUBLE_SIZE_96)
-	float96 data;
-#elif defined(DOUBLE_SIZE_128)
-	float128 data;
-#else
-	#error Unsupported double size
-#endif
-} double_t;
-
-typedef union {
-	long double val;
-	
-#if defined(LONG_DOUBLE_SIZE_32)
-	float32 data;
-#elif defined(LONG_DOUBLE_SIZE_64)
-	float64 data;
-#elif defined(LONG_DOUBLE_SIZE_96)
-	float96 data;
-#elif defined(LONG_DOUBLE_SIZE_128)
-	float128 data;
-#else
-	#error Unsupported long double size
-#endif
-} long_double_t;
+} float128_u;
+
+#endif
 
 #endif
Index: uspace/lib/math/include/mod.h
===================================================================
--- uspace/lib/math/include/mod.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/include/mod.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,5 +36,5 @@
 #define LIBMATH_MOD_H_
 
-extern double double_mod(double, double);
+extern float64_t float64_mod(float64_t, float64_t);
 
 #endif
Index: uspace/lib/math/include/trig.h
===================================================================
--- uspace/lib/math/include/trig.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/math/include/trig.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,6 +36,6 @@
 #define LIBMATH_TRIG_H_
 
-extern double double_sin(double);
-extern double double_cos(double);
+extern float64_t float64_sin(float64_t);
+extern float64_t float64_cos(float64_t);
 
 #endif
Index: uspace/lib/softfloat/Makefile
===================================================================
--- uspace/lib/softfloat/Makefile	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/Makefile	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -33,5 +33,4 @@
 
 SOURCES = \
-	softfloat.c \
 	common.c \
 	add.c \
@@ -39,4 +38,5 @@
 	div.c \
 	mul.c \
+	neg.c \
 	comparison.c \
 	conversion.c
Index: uspace/lib/softfloat/add.c
===================================================================
--- uspace/lib/softfloat/add.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/add.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,8 +34,8 @@
  */
 
-#include "sftypes.h"
 #include "add.h"
 #include "comparison.h"
 #include "common.h"
+#include "sub.h"
 
 /** Add two single-precision floats with the same sign.
@@ -413,4 +413,141 @@
 }
 
+#ifdef float32_t
+
+float32_t __addsf3(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		if (ua.data.parts.sign) {
+			ua.data.parts.sign = 0;
+			res.data = sub_float32(ub.data, ua.data);
+		} else {
+			ub.data.parts.sign = 0;
+			res.data = sub_float32(ua.data, ub.data);
+		}
+	} else
+		res.data = add_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float32_t __aeabi_fadd(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		if (ua.data.parts.sign) {
+			ua.data.parts.sign = 0;
+			res.data = sub_float32(ub.data, ua.data);
+		} else {
+			ub.data.parts.sign = 0;
+			res.data = sub_float32(ua.data, ub.data);
+		}
+	} else
+		res.data = add_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __adddf3(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		if (ua.data.parts.sign) {
+			ua.data.parts.sign = 0;
+			res.data = sub_float64(ub.data, ua.data);
+		} else {
+			ub.data.parts.sign = 0;
+			res.data = sub_float64(ua.data, ub.data);
+		}
+	} else
+		res.data = add_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float64_t __aeabi_dadd(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		if (ua.data.parts.sign) {
+			ua.data.parts.sign = 0;
+			res.data = sub_float64(ub.data, ua.data);
+		} else {
+			ub.data.parts.sign = 0;
+			res.data = sub_float64(ua.data, ub.data);
+		}
+	} else
+		res.data = add_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __addtf3(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	float128_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		if (ua.data.parts.sign) {
+			ua.data.parts.sign = 0;
+			res.data = sub_float128(ub.data, ua.data);
+		} else {
+			ub.data.parts.sign = 0;
+			res.data = sub_float128(ua.data, ub.data);
+		}
+	} else
+		res.data = add_float128(ua.data, ub.data);
+	
+	return res.val;
+}
+
+void _Qp_add(float128_t *c, float128_t *a, float128_t *b)
+{
+	*c = __addtf3(*a, *b);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/add.h
===================================================================
--- uspace/lib/softfloat/add.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/add.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -37,4 +37,6 @@
 #define __ADD_H__
 
+#include <mathtypes.h>
+
 extern float32 add_float32(float32, float32);
 extern float64 add_float64(float64, float64);
@@ -42,4 +44,19 @@
 extern float128 add_float128(float128, float128);
 
+#ifdef float32_t
+extern float32_t __addsf3(float32_t, float32_t);
+extern float32_t __aeabi_fadd(float32_t, float32_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __adddf3(float64_t, float64_t);
+extern float64_t __aeabi_dadd(float64_t, float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __addtf3(float128_t, float128_t);
+extern void _Qp_add(float128_t *, float128_t *, float128_t *);
+#endif
+
 #endif
 
Index: uspace/lib/softfloat/common.c
===================================================================
--- uspace/lib/softfloat/common.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/common.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,5 +34,4 @@
  */
 
-#include "sftypes.h"
 #include "common.h"
 
Index: uspace/lib/softfloat/common.h
===================================================================
--- uspace/lib/softfloat/common.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/common.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -37,5 +37,5 @@
 #define __COMMON_H__
 
-#include "sftypes.h"
+#include <mathtypes.h>
 
 extern float64 finish_float64(int32_t, uint64_t, char);
@@ -53,7 +53,10 @@
 extern void rshift128(uint64_t, uint64_t, int, uint64_t *, uint64_t *);
 
-extern void and128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
-extern void or128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
-extern void xor128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
+extern void and128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
+    uint64_t *);
+extern void or128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
+    uint64_t *);
+extern void xor128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
+    uint64_t *);
 extern void not128(uint64_t, uint64_t, uint64_t *, uint64_t *);
 
@@ -62,6 +65,8 @@
 extern int lt128(uint64_t, uint64_t, uint64_t, uint64_t);
 
-extern void add128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
-extern void sub128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *, uint64_t *);
+extern void add128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
+    uint64_t *);
+extern void sub128(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t *,
+    uint64_t *);
 
 extern void mul64(uint64_t, uint64_t, uint64_t *, uint64_t *);
Index: uspace/lib/softfloat/comparison.c
===================================================================
--- uspace/lib/softfloat/comparison.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/comparison.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,5 +34,4 @@
  */
 
-#include "sftypes.h"
 #include "comparison.h"
 #include "common.h"
@@ -439,4 +438,713 @@
 }
 
+#ifdef float32_t
+
+int __gtsf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float32_gt(ua.data, ub.data))
+		return 1;
+	
+	return 0;
+}
+
+int __gesf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float32_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float32_gt(ua.data, ub.data))
+		return 1;
+	
+	return -1;
+}
+
+int __ltsf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float32_lt(ua.data, ub.data))
+		return -1;
+	
+	return 0;
+}
+
+int __lesf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float32_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float32_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __eqsf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	return is_float32_eq(ua.data, ub.data) - 1;
+}
+
+int __nesf2(float32_t a, float32_t b)
+{
+	/* Strange, but according to GCC documentation */
+	return __eqsf2(a, b);
+}
+
+int __cmpsf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		/* No special constant for unordered - maybe signaled? */
+		return 1;
+	}
+	
+	if (is_float32_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float32_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __unordsf2(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	return ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data)));
+}
+
+int __aeabi_fcmpgt(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float32_gt(ua.data, ub.data))
+		return 1;
+	
+	return 0;
+}
+
+int __aeabi_fcmplt(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float32_lt(ua.data, ub.data))
+		return -1;
+	
+	return 0;
+}
+
+int __aeabi_fcmpge(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float32_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float32_gt(ua.data, ub.data))
+		return 1;
+	
+	return -1;
+}
+
+int __aeabi_fcmpeq(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	if ((is_float32_nan(ua.data)) || (is_float32_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	return is_float32_eq(ua.data, ub.data) - 1;
+}
+
+#endif
+
+#ifdef float64_t
+
+int __gtdf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float64_gt(ua.data, ub.data))
+		return 1;
+	
+	return 0;
+}
+
+int __gedf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float64_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float64_gt(ua.data, ub.data))
+		return 1;
+	
+	return -1;
+}
+
+int __ltdf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float64_lt(ua.data, ub.data))
+		return -1;
+	
+	return 0;
+}
+
+int __ledf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float64_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float64_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __eqdf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	return is_float64_eq(ua.data, ub.data) - 1;
+}
+
+int __nedf2(float64_t a, float64_t b)
+{
+	/* Strange, but according to GCC documentation */
+	return __eqdf2(a, b);
+}
+
+int __cmpdf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		/* No special constant for unordered - maybe signaled? */
+		return 1;
+	}
+	
+	if (is_float64_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float64_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __unorddf2(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	return ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data)));
+}
+
+int __aeabi_dcmplt(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float64_lt(ua.data, ub.data))
+		return -1;
+	
+	return 0;
+}
+
+int __aeabi_dcmpeq(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	return is_float64_eq(ua.data, ub.data) - 1;
+}
+
+int __aeabi_dcmpgt(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float64_gt(ua.data, ub.data))
+		return 1;
+	
+	return 0;
+}
+
+int __aeabi_dcmpge(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float64_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float64_gt(ua.data, ub.data))
+		return 1;
+	
+	return -1;
+}
+
+int __aeabi_dcmple(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	if ((is_float64_nan(ua.data)) || (is_float64_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float64_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float64_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+#endif
+
+#ifdef float128_t
+
+int __gttf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float128_gt(ua.data, ub.data))
+		return 1;
+	
+	return 0;
+}
+
+int __getf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		// TODO: sigNaNs
+		return -1;
+	}
+	
+	if (is_float128_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float128_gt(ua.data, ub.data))
+		return 1;
+	
+	return -1;
+}
+
+int __lttf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float128_lt(ua.data, ub.data))
+		return -1;
+	
+	return 0;
+}
+
+int __letf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	if (is_float128_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float128_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __eqtf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		// TODO: sigNaNs
+		return 1;
+	}
+	
+	return is_float128_eq(ua.data, ub.data) - 1;
+}
+
+int __netf2(float128_t a, float128_t b)
+{
+	/* Strange, but according to GCC documentation */
+	return __eqtf2(a, b);
+}
+
+int __cmptf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data))) {
+		/* No special constant for unordered - maybe signaled? */
+		return 1;
+	}
+	
+	if (is_float128_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float128_lt(ua.data, ub.data))
+		return -1;
+	
+	return 1;
+}
+
+int __unordtf2(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	return ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)));
+}
+
+int _Qp_cmp(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 3;
+	
+	if (is_float128_eq(ua.data, ub.data))
+		return 0;
+	
+	if (is_float128_lt(ua.data, ub.data))
+		return 1;
+	
+	return 2;
+}
+
+int _Qp_cmpe(float128_t *a, float128_t *b)
+{
+	/* Strange, but according to SPARC Compliance Definition */
+	return _Qp_cmp(a, b);
+}
+
+int _Qp_fgt(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return is_float128_gt(ua.data, ub.data);
+}
+
+int _Qp_fge(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return is_float128_eq(ua.data, ub.data) ||
+	    is_float128_gt(ua.data, ub.data);
+}
+
+int _Qp_flt(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return is_float128_lt(ua.data, ub.data);
+}
+
+int _Qp_fle(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return is_float128_eq(ua.data, ub.data) ||
+	    is_float128_lt(ua.data, ub.data);
+}
+
+int _Qp_feq(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return is_float128_eq(ua.data, ub.data);
+}
+
+int _Qp_fne(float128_t *a, float128_t *b)
+{
+	float128_u ua;
+	ua.val = *a;
+	
+	float128_u ub;
+	ub.val = *b;
+	
+	if ((is_float128_nan(ua.data)) || (is_float128_nan(ub.data)))
+		return 0;
+	
+	return !is_float128_eq(ua.data, ub.data);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/comparison.h
===================================================================
--- uspace/lib/softfloat/comparison.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/comparison.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,4 +36,6 @@
 #ifndef __COMPARISON_H__
 #define __COMPARISON_H__
+
+#include <mathtypes.h>
 
 extern int is_float32_nan(float32);
@@ -77,4 +79,55 @@
 extern int is_float128_gt(float128, float128);
 
+#ifdef float32_t
+extern int __gtsf2(float32_t, float32_t);
+extern int __gesf2(float32_t, float32_t);
+extern int __ltsf2(float32_t, float32_t);
+extern int __lesf2(float32_t, float32_t);
+extern int __eqsf2(float32_t, float32_t);
+extern int __nesf2(float32_t, float32_t);
+extern int __cmpsf2(float32_t, float32_t);
+extern int __unordsf2(float32_t, float32_t);
+extern int __aeabi_fcmpgt(float32_t, float32_t);
+extern int __aeabi_fcmplt(float32_t, float32_t);
+extern int __aeabi_fcmpge(float32_t, float32_t);
+extern int __aeabi_fcmpeq(float32_t, float32_t);
+#endif
+
+#ifdef float64_t
+extern int __gtdf2(float64_t, float64_t);
+extern int __gedf2(float64_t, float64_t);
+extern int __ltdf2(float64_t, float64_t);
+extern int __ledf2(float64_t, float64_t);
+extern int __eqdf2(float64_t, float64_t);
+extern int __nedf2(float64_t, float64_t);
+extern int __cmpdf2(float64_t, float64_t);
+extern int __unorddf2(float64_t, float64_t);
+extern int __aeabi_dcmplt(float64_t, float64_t);
+extern int __aeabi_dcmpeq(float64_t, float64_t);
+extern int __aeabi_dcmpgt(float64_t, float64_t);
+extern int __aeabi_dcmpge(float64_t, float64_t);
+extern int __aeabi_dcmple(float64_t, float64_t);
+#endif
+
+#ifdef float128_t
+extern int __gttf2(float128_t, float128_t);
+extern int __getf2(float128_t, float128_t);
+extern int __lttf2(float128_t, float128_t);
+extern int __letf2(float128_t, float128_t);
+extern int __eqtf2(float128_t, float128_t);
+extern int __netf2(float128_t, float128_t);
+extern int __cmptf2(float128_t, float128_t);
+extern int __unordtf2(float128_t, float128_t);
+extern int _Qp_cmp(float128_t *, float128_t *);
+extern int _Qp_cmpe(float128_t *, float128_t *);
+extern int _Qp_fgt(float128_t *, float128_t *);
+extern int _Qp_fge(float128_t *, float128_t *);
+extern int _Qp_flt(float128_t *, float128_t *);
+extern int _Qp_fle(float128_t *, float128_t *);
+extern int _Qp_feq(float128_t *, float128_t *);
+extern int _Qp_fne(float128_t *, float128_t *);
+
+#endif
+
 #endif
 
Index: uspace/lib/softfloat/conversion.c
===================================================================
--- uspace/lib/softfloat/conversion.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/conversion.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,5 +34,4 @@
  */
 
-#include "sftypes.h"
 #include "conversion.h"
 #include "comparison.h"
@@ -1037,4 +1036,464 @@
 }
 
+#ifdef float32_t
+
+float32_t __floatsisf(int32_t i)
+{
+	float32_u res;
+	res.data = int32_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __floatdisf(int64_t i)
+{
+	float32_u res;
+	res.data = int64_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __floatunsisf(uint32_t i)
+{
+	float32_u res;
+	res.data = uint32_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __floatundisf(uint64_t i)
+{
+	float32_u res;
+	res.data = uint64_to_float32(i);
+	
+	return res.val;
+}
+
+int32_t __fixsfsi(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_int32(ua.data);
+}
+
+int64_t __fixsfdi(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_int64(ua.data);
+}
+
+uint32_t __fixunssfsi(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_uint32(ua.data);
+}
+
+uint64_t __fixunssfdi(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_uint64(ua.data);
+}
+
+int32_t __aeabi_f2iz(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_int32(ua.data);
+}
+
+uint32_t __aeabi_f2uiz(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	return float32_to_uint32(ua.data);
+}
+
+float32_t __aeabi_i2f(int32_t i)
+{
+	float32_u res;
+	res.data = int32_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __aeabi_l2f(int64_t i)
+{
+	float32_u res;
+	res.data = int64_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __aeabi_ui2f(uint32_t i)
+{
+	float32_u res;
+	res.data = uint32_to_float32(i);
+	
+	return res.val;
+}
+
+float32_t __aeabi_ul2f(uint64_t i)
+{
+	float32_u res;
+	res.data = uint64_to_float32(i);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __floatsidf(int32_t i)
+{
+	float64_u res;
+	res.data = int32_to_float64(i);
+	
+	return res.val;
+}
+
+float64_t __floatdidf(int64_t i)
+{
+	float64_u res;
+	res.data = int64_to_float64(i);
+	
+	return res.val;
+}
+
+float64_t __floatunsidf(uint32_t i)
+{
+	float64_u res;
+	res.data = uint32_to_float64(i);
+	
+	return res.val;
+}
+
+float64_t __floatundidf(uint64_t i)
+{
+	float64_u res;
+	res.data = uint64_to_float64(i);
+	
+	return res.val;
+}
+
+uint32_t __fixunsdfsi(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_uint32(ua.data);
+}
+
+uint64_t __fixunsdfdi(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_uint64(ua.data);
+}
+
+int32_t __fixdfsi(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_int32(ua.data);
+}
+
+int64_t __fixdfdi(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_int64(ua.data);
+}
+
+float64_t __aeabi_i2d(int32_t i)
+{
+	float64_u res;
+	res.data = int32_to_float64(i);
+	
+	return res.val;
+}
+
+float64_t __aeabi_ui2d(uint32_t i)
+{
+	float64_u res;
+	res.data = uint32_to_float64(i);
+	
+	return res.val;
+}
+
+float64_t __aeabi_l2d(int64_t i)
+{
+	float64_u res;
+	res.data = int64_to_float64(i);
+	
+	return res.val;
+}
+
+int32_t __aeabi_d2iz(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_int32(ua.data);
+}
+
+int64_t __aeabi_d2lz(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_int64(ua.data);
+}
+
+uint32_t __aeabi_d2uiz(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	return float64_to_uint32(ua.data);
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __floatsitf(int32_t i)
+{
+	float128_u res;
+	res.data = int32_to_float128(i);
+	
+	return res.val;
+}
+
+float128_t __floatditf(int64_t i)
+{
+	float128_u res;
+	res.data = int64_to_float128(i);
+	
+	return res.val;
+}
+
+float128_t __floatunsitf(uint32_t i)
+{
+	float128_u res;
+	res.data = uint32_to_float128(i);
+	
+	return res.val;
+}
+
+float128_t __floatunditf(uint64_t i)
+{
+	float128_u res;
+	res.data = uint64_to_float128(i);
+	
+	return res.val;
+}
+
+int32_t __fixtfsi(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	return float128_to_int32(ua.data);
+}
+
+int64_t __fixtfdi(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	return float128_to_uint64(ua.data);
+}
+
+uint32_t __fixunstfsi(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	return float128_to_uint32(ua.data);
+}
+
+uint64_t __fixunstfdi(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	return float128_to_uint64(ua.data);
+}
+
+int32_t _Qp_qtoi(float128_t *a)
+{
+	return __fixtfsi(*a);
+}
+
+int64_t _Qp_qtox(float128_t *a)
+{
+	return __fixunstfdi(*a);
+}
+
+uint32_t _Qp_qtoui(float128_t *a)
+{
+	return __fixunstfsi(*a);
+}
+
+uint64_t _Qp_qtoux(float128_t *a)
+{
+	return __fixunstfdi(*a);
+}
+
+void _Qp_itoq(float128_t *c, int32_t a)
+{
+	*c = __floatsitf(a);
+}
+
+void _Qp_xtoq(float128_t *c, int64_t a)
+{
+	*c = __floatditf(a);
+}
+
+void _Qp_uitoq(float128_t *c, uint32_t a)
+{
+	*c = __floatunsitf(a);
+}
+
+void _Qp_uxtoq(float128_t *c, uint64_t a)
+{
+	*c = __floatunditf(a);
+}
+
+#endif
+
+#if (defined(float32_t) && defined(float64_t))
+
+float32_t __truncdfsf2(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float32_u res;
+	res.data = float64_to_float32(ua.data);
+	
+	return res.val;
+}
+
+float64_t __extendsfdf2(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float64_u res;
+	res.data = float32_to_float64(ua.data);
+	
+	return res.val;
+}
+
+float64_t __aeabi_f2d(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float64_u res;
+	res.data = float32_to_float64(ua.data);
+	
+	return res.val;
+}
+
+float32_t __aeabi_d2f(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float32_u res;
+	res.data = float64_to_float32(ua.data);
+	
+	return res.val;
+}
+
+#endif
+
+#if (defined(float32_t) && defined(float128_t))
+
+float32_t __trunctfsf2(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float32_u res;
+	res.data = float128_to_float32(ua.data);
+	
+	return res.val;
+}
+
+float128_t __extendsftf2(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float128_u res;
+	res.data = float32_to_float128(ua.data);
+	
+	return res.val;
+}
+
+void _Qp_stoq(float128_t *c, float32_t a)
+{
+	*c = __extendsftf2(a);
+}
+
+float32_t _Qp_qtos(float128_t *a)
+{
+	return __trunctfsf2(*a);
+}
+
+#endif
+
+#if (defined(float64_t) && defined(float128_t))
+
+float64_t __trunctfdf2(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float64_u res;
+	res.data = float128_to_float64(ua.data);
+	
+	return res.val;
+}
+
+float128_t __extenddftf2(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float128_u res;
+	res.data = float64_to_float128(ua.data);
+	
+	return res.val;
+}
+
+void _Qp_dtoq(float128_t *c, float64_t a)
+{
+	*c = __extenddftf2(a);
+}
+
+float64_t _Qp_qtod(float128_t *a)
+{
+	return __trunctfdf2(*a);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/conversion.h
===================================================================
--- uspace/lib/softfloat/conversion.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/conversion.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -36,4 +36,6 @@
 #ifndef __CONVERSION_H__
 #define __CONVERSION_H__
+
+#include <mathtypes.h>
 
 extern float64 float32_to_float64(float32);
@@ -99,4 +101,78 @@
 extern float128 int64_to_float128(int64_t);
 
+#ifdef float32_t
+extern float32_t __floatsisf(int32_t);
+extern float32_t __floatdisf(int64_t);
+extern float32_t __floatunsisf(uint32_t);
+extern float32_t __floatundisf(uint64_t);
+extern int32_t __fixsfsi(float32_t);
+extern int64_t __fixsfdi(float32_t);
+extern uint32_t __fixunssfsi(float32_t);
+extern uint64_t __fixunssfdi(float32_t);
+extern int32_t __aeabi_f2iz(float32_t);
+extern uint32_t __aeabi_f2uiz(float32_t);
+extern float32_t __aeabi_i2f(int32_t);
+extern float32_t __aeabi_l2f(int64_t);
+extern float32_t __aeabi_ui2f(uint32_t);
+extern float32_t __aeabi_ul2f(uint64_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __floatsidf(int32_t);
+extern float64_t __floatdidf(int64_t);
+extern float64_t __floatunsidf(uint32_t);
+extern float64_t __floatundidf(uint64_t);
+extern int32_t __fixdfsi(float64_t);
+extern int64_t __fixdfdi(float64_t);
+extern uint32_t __fixunsdfsi(float64_t);
+extern uint64_t __fixunsdfdi(float64_t);
+extern float64_t __aeabi_i2d(int32_t);
+extern float64_t __aeabi_ui2d(uint32_t);
+extern float64_t __aeabi_l2d(int64_t);
+extern int32_t __aeabi_d2iz(float64_t);
+extern int64_t __aeabi_d2lz(float64_t);
+extern uint32_t __aeabi_d2uiz(float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __floatsitf(int32_t);
+extern float128_t __floatditf(int64_t);
+extern float128_t __floatunsitf(uint32_t);
+extern float128_t __floatunditf(uint64_t);
+extern int32_t __fixtfsi(float128_t);
+extern int64_t __fixtfdi(float128_t);
+extern uint32_t __fixunstfsi(float128_t);
+extern uint64_t __fixunstfdi(float128_t);
+extern int32_t _Qp_qtoi(float128_t *);
+extern int64_t _Qp_qtox(float128_t *);
+extern uint32_t _Qp_qtoui(float128_t *);
+extern uint64_t _Qp_qtoux(float128_t *);
+extern void _Qp_itoq(float128_t *, int32_t);
+extern void _Qp_xtoq(float128_t *, int64_t);
+extern void _Qp_uitoq(float128_t *, uint32_t);
+extern void _Qp_uxtoq(float128_t *, uint64_t);
+#endif
+
+#if (defined(float32_t) && defined(float64_t))
+extern float32_t __truncdfsf2(float64_t);
+extern float64_t __extendsfdf2(float32_t);
+extern float64_t __aeabi_f2d(float32_t);
+extern float32_t __aeabi_d2f(float64_t);
+#endif
+
+#if (defined(float32_t) && defined(float128_t))
+extern float32_t __trunctfsf2(float128_t);
+extern float128_t __extendsftf2(float32_t);
+extern void _Qp_stoq(float128_t *, float32_t);
+extern float32_t _Qp_qtos(float128_t *);
+#endif
+
+#if (defined(float64_t) && defined(float128_t))
+extern float64_t __trunctfdf2(float128_t);
+extern float128_t __extenddftf2(float64_t);
+extern void _Qp_dtoq(float128_t *, float64_t);
+extern float64_t _Qp_qtod(float128_t *);
+#endif
+
 #endif
 
Index: uspace/lib/softfloat/div.c
===================================================================
--- uspace/lib/softfloat/div.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/div.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,5 +34,4 @@
  */
 
-#include "sftypes.h"
 #include "add.h"
 #include "div.h"
@@ -539,4 +538,91 @@
 }
 
+#ifdef float32_t
+
+float32_t __divsf3(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	res.data = div_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float32_t __aeabi_fdiv(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	res.data = div_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __divdf3(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	res.data = div_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float64_t __aeabi_ddiv(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	res.data = div_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __divtf3(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	float128_u res;
+	res.data = div_float128(ua.data, ub.data);
+	
+	return res.val;
+}
+
+void _Qp_div(float128_t *c, float128_t *a, float128_t *b)
+{
+	*c = __divtf3(*a, *b);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/div.h
===================================================================
--- uspace/lib/softfloat/div.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/div.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -42,4 +42,19 @@
 extern float128 div_float128(float128, float128);
 
+#ifdef float32_t
+extern float32_t __divsf3(float32_t, float32_t);
+extern float32_t __aeabi_fdiv(float32_t, float32_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __divdf3(float64_t, float64_t);
+extern float64_t __aeabi_ddiv(float64_t, float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __divtf3(float128_t, float128_t);
+extern void _Qp_div(float128_t *, float128_t *, float128_t *);
+#endif
+
 #endif
 
Index: uspace/lib/softfloat/mul.c
===================================================================
--- uspace/lib/softfloat/mul.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/mul.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,5 +34,4 @@
  */
 
-#include "sftypes.h"
 #include "mul.h"
 #include "comparison.h"
@@ -62,4 +61,5 @@
 			return result;
 		}
+		
 		if (is_float32_signan(b)) { /* TODO: fix SigNaN */
 			result.parts.fraction = b.parts.fraction;
@@ -67,4 +67,5 @@
 			return result;
 		}
+		
 		/* set NaN as result */
 		result.bin = FLOAT32_NAN;
@@ -78,4 +79,5 @@
 			return result;
 		}
+		
 		result.parts.fraction = a.parts.fraction;
 		result.parts.exp = a.parts.exp;
@@ -89,4 +91,5 @@
 			return result;
 		}
+		
 		result.parts.fraction = b.parts.fraction;
 		result.parts.exp = b.parts.exp;
@@ -106,5 +109,5 @@
 	}
 	
-	if (exp < 0) { 
+	if (exp < 0) {
 		/* FIXME: underflow */
 		/* return signed zero */
@@ -164,8 +167,10 @@
 		/* denormalized number */
 		frac1 >>= 1; /* denormalize */
+		
 		while ((frac1 > 0) && (exp < 0)) {
 			frac1 >>= 1;
 			++exp;
 		}
+		
 		if (frac1 == 0) {
 			/* FIXME : underflow */
@@ -175,4 +180,5 @@
 		}
 	}
+	
 	result.parts.exp = exp; 
 	result.parts.fraction = frac1 & ((1 << FLOAT32_FRACTION_SIZE) - 1);
@@ -380,4 +386,91 @@
 }
 
+#ifdef float32_t
+
+float32_t __mulsf3(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	res.data = mul_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float32_t __aeabi_fmul(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	res.data = mul_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __muldf3(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	res.data = mul_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float64_t __aeabi_dmul(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	res.data = mul_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __multf3(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	float128_u res;
+	res.data = mul_float128(ua.data, ub.data);
+	
+	return res.val;
+}
+
+void _Qp_mul(float128_t *c, float128_t *a, float128_t *b)
+{
+	*c = __multf3(*a, *b);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/mul.h
===================================================================
--- uspace/lib/softfloat/mul.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/mul.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -37,4 +37,6 @@
 #define __MUL_H__
 
+#include <mathtypes.h>
+
 extern float32 mul_float32(float32, float32);
 extern float64 mul_float64(float64, float64);
@@ -42,4 +44,19 @@
 extern float128 mul_float128(float128, float128);
 
+#ifdef float32_t
+extern float32_t __mulsf3(float32_t, float32_t);
+extern float32_t __aeabi_fmul(float32_t, float32_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __muldf3(float64_t, float64_t);
+extern float64_t __aeabi_dmul(float64_t, float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __multf3(float128_t, float128_t);
+extern void _Qp_mul(float128_t *, float128_t *, float128_t *);
+#endif
+
 #endif
 
Index: uspace/lib/softfloat/neg.c
===================================================================
--- uspace/lib/softfloat/neg.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/lib/softfloat/neg.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * Copyright (c) 2011 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup softfloat
+ * @{
+ */
+/** @file Negation functions.
+ */
+
+#include "neg.h"
+#include "common.h"
+
+#ifdef float32_t
+
+float32_t __negsf2(float32_t a)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	ua.data.parts.sign = !ua.data.parts.sign;
+	
+	return ua.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __negdf2(float64_t a)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	ua.data.parts.sign = !ua.data.parts.sign;
+	
+	return ua.val;
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __negtf2(float128_t a)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	ua.data.parts.sign = !ua.data.parts.sign;
+	
+	return ua.val;
+}
+
+void _Qp_neg(float128_t *c, float128_t *a)
+{
+	*c = __negtf2(*a);
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/neg.h
===================================================================
--- uspace/lib/softfloat/neg.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
+++ uspace/lib/softfloat/neg.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * Copyright (c) 2011 Petr Koupy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup softfloat
+ * @{
+ */
+/** @file Negation functions.
+ */
+
+#ifndef __NEG_H__
+#define __NEG_H__
+
+#include <mathtypes.h>
+
+#ifdef float32_t
+extern float32_t __negsf2(float32_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __negdf2(float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __negtf2(float128_t);
+extern void _Qp_neg(float128_t *, float128_t *);
+#endif
+
+#endif
+
+/** @}
+ */
Index: pace/lib/softfloat/sftypes.h
===================================================================
--- uspace/lib/softfloat/sftypes.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ 	(revision )
@@ -1,406 +1,0 @@
-/*
- * Copyright (c) 2005 Josef Cejka
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup softfloat
- * @{
- */
-/** @file Floating point types and constants.
- */
-
-#ifndef SOFTFLOAT_SFTYPES_H__
-#define SOFTFLOAT_SFTYPES_H__
-
-#include <mathtypes.h>
-
-#if defined(INT_SIZE_8)
-
-#define _to_int   _to_int8
-#define from_int  int8
-
-#elif defined(INT_SIZE_16)
-
-#define _to_int   _to_int16
-#define from_int  int16
-
-#elif defined(INT_SIZE_32)
-
-#define _to_int   _to_int32
-#define from_int  int32
-
-#elif defined(INT_SIZE_64)
-
-#define _to_int   _to_int64
-#define from_int  int64
-
-#endif
-
-
-#if defined(UINT_SIZE_8)
-
-#define _to_uint   _to_uint8
-#define from_uint  uint8
-
-#elif defined(UINT_SIZE_16)
-
-#define _to_uint   _to_uint16
-#define from_uint  uint16
-
-#elif defined(UINT_SIZE_32)
-
-#define _to_uint   _to_uint32
-#define from_uint  uint32
-
-#elif defined(UINT_SIZE_64)
-
-#define _to_uint   _to_uint64
-#define from_uint  uint64
-
-#endif
-
-
-#if defined(LONG_SIZE_8)
-
-#define _to_long   _to_int8
-#define from_long  int8
-
-#elif defined(LONG_SIZE_16)
-
-#define _to_long   _to_int16
-#define from_long  int16
-
-#elif defined(LONG_SIZE_32)
-
-#define _to_long   _to_int32
-#define from_long  int32
-
-#elif defined(LONG_SIZE_64)
-
-#define _to_long   _to_int64
-#define from_long  int64
-
-#endif
-
-
-#if defined(ULONG_SIZE_8)
-
-#define _to_ulong   _to_uint8
-#define from_ulong  uint8
-
-#elif defined(ULONG_SIZE_16)
-
-#define _to_ulong   _to_uint16
-#define from_ulong  uint16
-
-#elif defined(ULONG_SIZE_32)
-
-#define _to_ulong   _to_uint32
-#define from_ulong  uint32
-
-#elif defined(ULONG_SIZE_64)
-
-#define _to_ulong   _to_uint64
-#define from_ulong  uint64
-
-#endif
-
-
-#if defined(LLONG_SIZE_8)
-
-#define _to_llong   _to_int8
-#define from_llong  int8
-
-#elif defined(LLONG_SIZE_16)
-
-#define _to_llong   _to_int16
-#define from_llong  int16
-
-#elif defined(LLONG_SIZE_32)
-
-#define _to_llong   _to_int32
-#define from_llong  int32
-
-#elif defined(LLONG_SIZE_64)
-
-#define _to_llong   _to_int64
-#define from_llong  int64
-
-#endif
-
-
-#if defined(ULLONG_SIZE_8)
-
-#define _to_ullong   _to_uint8
-#define from_ullong  uint8
-
-#elif defined(ULLONG_SIZE_16)
-
-#define _to_ullong   _to_uint16
-#define from_ullong  uint16
-
-#elif defined(ULLONG_SIZE_32)
-
-#define _to_ullong   _to_uint32
-#define from_ullong  uint32
-
-#elif defined(ULLONG_SIZE_64)
-
-#define _to_ullong   _to_uint64
-#define from_ullong  uint64
-
-#endif
-
-
-#if defined(FLOAT_SIZE_32)
-
-#define add_float     add_float32
-#define sub_float     sub_float32
-#define mul_float     mul_float32
-#define div_float     div_float32
-#define _to_float     _to_float32
-#define from_float    float32
-#define is_float_nan  is_float32_nan
-#define is_float_eq   is_float32_eq
-#define is_float_lt   is_float32_lt
-#define is_float_gt   is_float32_gt
-
-#elif defined(FLOAT_SIZE_64)
-
-#define add_float     add_float64
-#define sub_float     sub_float64
-#define mul_float     mul_float64
-#define div_float     div_float64
-#define _to_float     _to_float64
-#define from_float    float64
-#define is_float_nan  is_float64_nan
-#define is_float_eq   is_float64_eq
-#define is_float_lt   is_float64_lt
-#define is_float_gt   is_float64_gt
-
-#elif defined(FLOAT_SIZE_96)
-
-#define add_float     add_float96
-#define sub_float     sub_float96
-#define mul_float     mul_float96
-#define div_float     div_float96
-#define _to_float     _to_float96
-#define from_float    float96
-#define is_float_nan  is_float96_nan
-#define is_float_eq   is_float96_eq
-#define is_float_lt   is_float96_lt
-#define is_float_gt   is_float96_gt
-
-#elif defined(FLOAT_SIZE_128)
-
-#define add_float     add_float128
-#define sub_float     sub_float128
-#define mul_float     mul_float128
-#define div_float     div_float128
-#define _to_float     _to_float128
-#define from_float    float128
-#define is_float_nan  is_float128_nan
-#define is_float_eq   is_float128_eq
-#define is_float_lt   is_float128_lt
-#define is_float_gt   is_float128_gt
-
-#endif
-
-
-#if defined(DOUBLE_SIZE_32)
-
-#define add_double     add_float32
-#define sub_double     sub_float32
-#define mul_double     mul_float32
-#define div_double     div_float32
-#define _to_double     _to_float32
-#define from_double    float32
-#define is_double_nan  is_float32_nan
-#define is_double_eq   is_float32_eq
-#define is_double_lt   is_float32_lt
-#define is_double_gt   is_float32_gt
-
-#elif defined(DOUBLE_SIZE_64)
-
-#define add_double     add_float64
-#define sub_double     sub_float64
-#define mul_double     mul_float64
-#define div_double     div_float64
-#define _to_double     _to_float64
-#define from_double    float64
-#define is_double_nan  is_float64_nan
-#define is_double_eq   is_float64_eq
-#define is_double_lt   is_float64_lt
-#define is_double_gt   is_float64_gt
-
-#elif defined(DOUBLE_SIZE_96)
-
-#define add_double     add_float96
-#define sub_double     sub_float96
-#define mul_double     mul_float96
-#define div_double     div_float96
-#define _to_double     _to_float96
-#define from_double    float96
-#define is_double_nan  is_float96_nan
-#define is_double_eq   is_float96_eq
-#define is_double_lt   is_float96_lt
-#define is_double_gt   is_float96_gt
-
-#elif defined(DOUBLE_SIZE_128)
-
-#define add_double     add_float128
-#define sub_double     sub_float128
-#define mul_double     mul_float128
-#define div_double     div_float128
-#define _to_double     _to_float128
-#define from_double    float128
-#define is_double_nan  is_float128_nan
-#define is_double_eq   is_float128_eq
-#define is_double_lt   is_float128_lt
-#define is_double_gt   is_float128_gt
-
-#endif
-
-
-#if defined(LONG_DOUBLE_SIZE_32)
-
-#define add_long_double     add_float32
-#define sub_long_double     sub_float32
-#define mul_long_double     mul_float32
-#define div_long_double     div_float32
-#define _to_long_double     _to_float32
-#define from_long_double    float32
-#define is_long_double_nan  is_float32_nan
-#define is_long_double_eq   is_float32_eq
-#define is_long_double_lt   is_float32_lt
-#define is_long_double_gt   is_float32_gt
-
-#elif defined(LONG_DOUBLE_SIZE_64)
-
-#define add_long_double     add_float64
-#define sub_long_double     sub_float64
-#define mul_long_double     mul_float64
-#define div_long_double     div_float64
-#define _to_long_double     _to_float64
-#define from_long_double    float64
-#define is_long_double_nan  is_float64_nan
-#define is_long_double_eq   is_float64_eq
-#define is_long_double_lt   is_float64_lt
-#define is_long_double_gt   is_float64_gt
-
-#elif defined(LONG_DOUBLE_SIZE_96)
-
-#define add_long_double     add_float96
-#define sub_long_double     sub_float96
-#define mul_long_double     mul_float96
-#define div_long_double     div_float96
-#define _to_long_double     _to_float96
-#define from_long_double    float96
-#define is_long_double_nan  is_float96_nan
-#define is_long_double_eq   is_float96_eq
-#define is_long_double_lt   is_float96_lt
-#define is_long_double_gt   is_float96_gt
-
-#elif defined(LONG_DOUBLE_SIZE_128)
-
-#define add_long_double     add_float128
-#define sub_long_double     sub_float128
-#define mul_long_double     mul_float128
-#define div_long_double     div_float128
-#define _to_long_double     _to_float128
-#define from_long_double    float128
-#define is_long_double_nan  is_float128_nan
-#define is_long_double_eq   is_float128_eq
-#define is_long_double_lt   is_float128_lt
-#define is_long_double_gt   is_float128_gt
-
-#endif
-
-
-#define CONCAT(a, b)       CONCAT_ARGS(a, b)
-#define CONCAT_ARGS(a, b)  a ## b
-
-#define float32_to_float32(arg)    (arg)
-#define float64_to_float64(arg)    (arg)
-#define float96_to_float96(arg)    (arg)
-#define float128_to_float128(arg)  (arg)
-
-#define float_to_double       CONCAT(from_float, _to_double)
-#define float_to_long_double  CONCAT(from_float, _to_long_double)
-#define float_to_int          CONCAT(from_float, _to_int)
-#define float_to_uint         CONCAT(from_float, _to_uint)
-#define float_to_long         CONCAT(from_float, _to_long)
-#define float_to_ulong        CONCAT(from_float, _to_ulong)
-#define float_to_llong        CONCAT(from_float, _to_llong)
-#define float_to_ullong       CONCAT(from_float, _to_ullong)
-
-#define double_to_float        CONCAT(from_double, _to_float)
-#define double_to_long_double  CONCAT(from_double, _to_long_double)
-#define double_to_int          CONCAT(from_double, _to_int)
-#define double_to_uint         CONCAT(from_double, _to_uint)
-#define double_to_long         CONCAT(from_double, _to_long)
-#define double_to_ulong        CONCAT(from_double, _to_ulong)
-#define double_to_llong        CONCAT(from_double, _to_llong)
-#define double_to_ullong       CONCAT(from_double, _to_ullong)
-
-#define long_double_to_float   CONCAT(from_long_double, _to_float)
-#define long_double_to_double  CONCAT(from_long_double, _to_double)
-#define long_double_to_int     CONCAT(from_long_double, _to_int)
-#define long_double_to_uint    CONCAT(from_long_double, _to_uint)
-#define long_double_to_long    CONCAT(from_long_double, _to_long)
-#define long_double_to_ulong   CONCAT(from_long_double, _to_ulong)
-#define long_double_to_llong   CONCAT(from_long_double, _to_llong)
-#define long_double_to_ullong  CONCAT(from_long_double, _to_ullong)
-
-#define int_to_float        CONCAT(from_int, _to_float)
-#define int_to_double       CONCAT(from_int, _to_double)
-#define int_to_long_double  CONCAT(from_int, _to_long_double)
-
-#define uint_to_float        CONCAT(from_uint, _to_float)
-#define uint_to_double       CONCAT(from_uint, _to_double)
-#define uint_to_long_double  CONCAT(from_uint, _to_long_double)
-
-#define long_to_float        CONCAT(from_long, _to_float)
-#define long_to_double       CONCAT(from_long, _to_double)
-#define long_to_long_double  CONCAT(from_long, _to_long_double)
-
-#define ulong_to_float        CONCAT(from_ulong, _to_float)
-#define ulong_to_double       CONCAT(from_ulong, _to_double)
-#define ulong_to_long_double  CONCAT(from_ulong, _to_long_double)
-
-#define llong_to_float        CONCAT(from_llong, _to_float)
-#define llong_to_double       CONCAT(from_llong, _to_double)
-#define llong_to_long_double  CONCAT(from_llong, _to_long_double)
-
-#define ullong_to_float        CONCAT(from_ullong, _to_float)
-#define ullong_to_double       CONCAT(from_ullong, _to_double)
-#define ullong_to_long_double  CONCAT(from_ullong, _to_long_double)
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/softfloat.c
===================================================================
--- uspace/lib/softfloat/softfloat.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ 	(revision )
@@ -1,1423 +1,0 @@
-/*
- * Copyright (c) 2005 Josef Cejka
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup softfloat generic
- * @ingroup sfl
- * @brief Architecture independent parts of FPU software emulation library.
- * @{
- */
-/** @file Softfloat API.
- */
-
-#include "softfloat.h"
-#include "sftypes.h"
-#include "add.h"
-#include "sub.h"
-#include "mul.h"
-#include "div.h"
-#include "conversion.h"
-#include "comparison.h"
-
-/* Arithmetic functions */
-
-float __addsf3(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	float_t res;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if (fa.data.parts.sign != fb.data.parts.sign) {
-		if (fa.data.parts.sign) {
-			fa.data.parts.sign = 0;
-			res.data = sub_float(fb.data, fa.data);
-			
-			return res.val;
-		}
-		
-		fb.data.parts.sign = 0;
-		res.data = sub_float(fa.data, fb.data);
-		
-		return res.val;
-	}
-	
-	res.data = add_float(fa.data, fb.data);
-	return res.val;
-}
-
-double __adddf3(double a, double b)
-{
-	double_t da;
-	double_t db;
-	double_t res;
-	
-	da.val = a;
-	db.val = b;
-	
-	if (da.data.parts.sign != db.data.parts.sign) {
-		if (da.data.parts.sign) {
-			da.data.parts.sign = 0;
-			res.data = sub_double(db.data, da.data);
-			
-			return res.val;
-		}
-		
-		db.data.parts.sign = 0;
-		res.data = sub_double(da.data, db.data);
-		
-		return res.val;
-	}
-	
-	res.data = add_double(da.data, db.data);
-	return res.val;
-}
-
-long double __addtf3(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	long_double_t res;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if (ta.data.parts.sign != tb.data.parts.sign) {
-		if (ta.data.parts.sign) {
-			ta.data.parts.sign = 0;
-			res.data = sub_long_double(tb.data, ta.data);
-			
-			return res.val;
-		}
-		
-		tb.data.parts.sign = 0;
-		res.data = sub_long_double(ta.data, tb.data);
-		
-		return res.val;
-	}
-	
-	res.data = add_long_double(ta.data, tb.data);
-	return res.val;
-}
-
-float __subsf3(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	float_t res;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if (fa.data.parts.sign != fb.data.parts.sign) {
-		fb.data.parts.sign = !fb.data.parts.sign;
-		res.data = add_float(fa.data, fb.data);
-		
-		return res.val;
-	}
-	
-	res.data = sub_float(fa.data, fb.data);
-	return res.val;
-}
-
-double __subdf3(double a, double b)
-{
-	double_t da;
-	double_t db;
-	double_t res;
-	
-	da.val = a;
-	db.val = b;
-	
-	if (da.data.parts.sign != db.data.parts.sign) {
-		db.data.parts.sign = !db.data.parts.sign;
-		res.data = add_double(da.data, db.data);
-		
-		return res.val;
-	}
-	
-	res.data = sub_double(da.data, db.data);
-	return res.val;
-}
-
-long double __subtf3(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	long_double_t res;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if (ta.data.parts.sign != tb.data.parts.sign) {
-		tb.data.parts.sign = !tb.data.parts.sign;
-		res.data = add_long_double(ta.data, tb.data);
-		
-		return res.val;
-	}
-	
-	res.data = sub_long_double(ta.data, tb.data);
-	return res.val;
-}
-
-float __mulsf3(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	float_t res;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	res.data = mul_float(fa.data, fb.data);
-	return res.val;
-}
-
-double __muldf3(double a, double b)
-{
-	double_t da;
-	double_t db;
-	double_t res;
-	
-	da.val = a;
-	db.val = b;
-	
-	res.data = mul_double(da.data, db.data);
-	return res.val;
-}
-
-long double __multf3(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	long_double_t res;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	res.data = mul_long_double(ta.data, tb.data);
-	return res.val;
-}
-
-float __divsf3(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	float_t res;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	res.data = div_float(fa.data, fb.data);
-	return res.val;
-}
-
-double __divdf3(double a, double b)
-{
-	double_t da;
-	double_t db;
-	double_t res;
-	
-	da.val = a;
-	db.val = b;
-	
-	res.data = div_double(da.data, db.data);
-	return res.val;
-}
-
-long double __divtf3(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	long_double_t res;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	res.data = div_long_double(ta.data, tb.data);
-	return res.val;
-}
-
-float __negsf2(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	fa.data.parts.sign = !fa.data.parts.sign;
-	
-	return fa.val;
-}
-
-double __negdf2(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	da.data.parts.sign = !da.data.parts.sign;
-	
-	return da.val;
-}
-
-long double __negtf2(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	ta.data.parts.sign = !ta.data.parts.sign;
-	
-	return ta.val;
-}
-
-/* Conversion functions */
-
-double __extendsfdf2(float a)
-{
-	float_t fa;
-	double_t res;
-	
-	fa.val = a;
-	res.data = float_to_double(fa.data);
-	
-	return res.val;
-}
-
-long double __extendsftf2(float a)
-{
-	float_t fa;
-	long_double_t res;
-	
-	fa.val = a;
-	res.data = float_to_long_double(fa.data);
-	
-	return res.val;
-}
-
-long double __extenddftf2(double a)
-{
-	double_t da;
-	long_double_t res;
-	
-	da.val = a;
-	res.data = double_to_long_double(da.data);
-	
-	return res.val;
-}
-
-float __truncdfsf2(double a)
-{
-	double_t da;
-	float_t res;
-	
-	da.val = a;
-	res.data = double_to_float(da.data);
-	
-	return res.val;
-}
-
-float __trunctfsf2(long double a)
-{
-	long_double_t ta;
-	float_t res;
-	
-	ta.val = a;
-	res.data = long_double_to_float(ta.data);
-	
-	return res.val;
-}
-
-double __trunctfdf2(long double a)
-{
-	long_double_t ta;
-	double_t res;
-	
-	ta.val = a;
-	res.data = long_double_to_double(ta.data);
-	
-	return res.val;
-}
-
-int __fixsfsi(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_int(fa.data);
-}
-
-int __fixdfsi(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_int(da.data);
-}
-
-int __fixtfsi(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_int(ta.data);
-}
- 
-long __fixsfdi(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_long(fa.data);
-}
-
-long __fixdfdi(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_long(da.data);
-}
-
-long __fixtfdi(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_long(ta.data);
-}
- 
-long long __fixsfti(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_llong(fa.data);
-}
-
-long long __fixdfti(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_llong(da.data);
-}
-
-long long __fixtfti(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_llong(ta.data);
-}
-
-unsigned int __fixunssfsi(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_uint(fa.data);
-}
-
-unsigned int __fixunsdfsi(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_uint(da.data);
-}
-
-unsigned int __fixunstfsi(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_uint(ta.data);
-}
- 
-unsigned long __fixunssfdi(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_ulong(fa.data);
-}
-
-unsigned long __fixunsdfdi(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_ulong(da.data);
-}
-
-unsigned long __fixunstfdi(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_ulong(ta.data);
-}
- 
-unsigned long long __fixunssfti(float a)
-{
-	float_t fa;
-	
-	fa.val = a;
-	return float_to_ullong(fa.data);
-}
-
-unsigned long long __fixunsdfti(double a)
-{
-	double_t da;
-	
-	da.val = a;
-	return double_to_ullong(da.data);
-}
-
-unsigned long long __fixunstfti(long double a)
-{
-	long_double_t ta;
-	
-	ta.val = a;
-	return long_double_to_ullong(ta.data);
-}
- 
-float __floatsisf(int i)
-{
-	float_t res;
-	
-	res.data = int_to_float(i);
-	return res.val;
-}
-
-double __floatsidf(int i)
-{
-	double_t res;
-	
-	res.data = int_to_double(i);
-	return res.val;
-}
-
-long double __floatsitf(int i)
-{
-	long_double_t res;
-	
-	res.data = int_to_long_double(i);
-	return res.val;
-}
- 
-float __floatdisf(long i)
-{
-	float_t res;
-	
-	res.data = long_to_float(i);
-	return res.val;
-}
-
-double __floatdidf(long i)
-{
-	double_t res;
-	
-	res.data = long_to_double(i);
-	return res.val;
-}
-
-long double __floatditf(long i)
-{
-	long_double_t res;
-	
-	res.data = long_to_long_double(i);
-	return res.val;
-}
-
-float __floattisf(long long i)
-{
-	float_t res;
-	
-	res.data = llong_to_float(i);
-	return res.val;
-}
-
-double __floattidf(long long i)
-{
-	double_t res;
-	
-	res.data = llong_to_double(i);
-	return res.val;
-}
-
-long double __floattitf(long long i)
-{
-	long_double_t res;
-	
-	res.data = llong_to_long_double(i);
-	return res.val;
-}
-
-float __floatunsisf(unsigned int i)
-{
-	float_t res;
-	
-	res.data = uint_to_float(i);
-	return res.val;
-}
-
-double __floatunsidf(unsigned int i)
-{
-	double_t res;
-	
-	res.data = uint_to_double(i);
-	return res.val;
-}
-
-long double __floatunsitf(unsigned int i)
-{
-	long_double_t res;
-	
-	res.data = uint_to_long_double(i);
-	return res.val;
-}
- 
-float __floatundisf(unsigned long i)
-{
-	float_t res;
-	
-	res.data = ulong_to_float(i);
-	return res.val;
-}
-
-double __floatundidf(unsigned long i)
-{
-	double_t res;
-	
-	res.data = ulong_to_double(i);
-	return res.val;
-}
-
-long double __floatunditf(unsigned long i)
-{
-	long_double_t res;
-	
-	res.data = ulong_to_long_double(i);
-	return res.val;
-}
- 
-float __floatuntisf(unsigned long long i)
-{
-	float_t res;
-	
-	res.data = ullong_to_float(i);
-	return res.val;
-}
-
-double __floatuntidf(unsigned long long i)
-{
-	double_t res;
-	
-	res.data = ullong_to_double(i);
-	return res.val;
-}
-
-long double __floatuntitf(unsigned long long i)
-{
-	long_double_t res;
-	
-	res.data = ullong_to_long_double(i);
-	return res.val;
-}
-
-/* Comparison functions */
-
-int __cmpsf2(float a, float b) 
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		/* no special constant for unordered - maybe signaled? */
-		return 1;
-	}
-	
-	if (is_float_eq(fa.data, fb.data))
-		return 0;
-	
-	if (is_float_lt(fa.data, fb.data))
-		return -1;
-	
-	return 1;
-}
-
-int __cmpdf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		/* no special constant for unordered - maybe signaled? */
-		return 1;
-	}
-	
-	if (is_double_eq(da.data, db.data))
-		return 0;
-	
-	if (is_double_lt(da.data, db.data))
-		return -1;
-	
-	return 1;
-}
-
-int __cmptf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		/* no special constant for unordered - maybe signaled? */
-		return 1;
-	}
-	
-	if (is_long_double_eq(ta.data, tb.data))
-		return 0;
-	
-	if (is_long_double_lt(ta.data, tb.data))
-		return -1;
-	
-	return 1;
-}
-
-int __unordsf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	return ((is_float_nan(fa.data)) || (is_float_nan(fb.data)));
-}
-
-int __unorddf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	return ((is_double_nan(da.data)) || (is_double_nan(db.data)));
-}
-
-int __unordtf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	return ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)));
-}
-
-int __eqsf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	return is_float_eq(fa.data, fb.data) - 1;
-}
-
-int __eqdf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	return is_double_eq(da.data, db.data) - 1;
-}
-
-int __eqtf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	return is_long_double_eq(ta.data, tb.data) - 1;
-}
-
-int __nesf2(float a, float b)
-{
-	/* strange behavior, but it was in gcc documentation */
-	return __eqsf2(a, b);
-}
-
-int __nedf2(double a, double b)
-{
-	/* strange behavior, but it was in gcc documentation */
-	return __eqdf2(a, b);
-}
-
-int __netf2(long double a, long double b)
-{
-	/* strange behavior, but it was in gcc documentation */
-	return __eqtf2(a, b);
-}
-
-int __gesf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_float_eq(fa.data, fb.data))
-		return 0;
-	
-	if (is_float_gt(fa.data, fb.data))
-		return 1;
-	
-	return -1;
-}
-
-int __gedf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_double_eq(da.data, db.data))
-		return 0;
-	
-	if (is_double_gt(da.data, db.data))
-		return 1;
-	
-	return -1;
-}
-
-int __getf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_long_double_eq(ta.data, tb.data))
-		return 0;
-	
-	if (is_long_double_gt(ta.data, tb.data))
-		return 1;
-	
-	return -1;
-}
-
-int __ltsf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_float_lt(fa.data, fb.data))
-		return -1;
-	
-	return 0;
-}
-
-int __ltdf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_double_lt(da.data, db.data))
-		return -1;
-	
-	return 0;
-}
-
-int __lttf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_long_double_lt(ta.data, tb.data))
-		return -1;
-	
-	return 0;
-}
-
-int __lesf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_float_eq(fa.data, fb.data))
-		return 0;
-	
-	if (is_float_lt(fa.data, fb.data))
-		return -1;
-	
-	return 1;
-}
-
-int __ledf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_double_eq(da.data, db.data))
-		return 0;
-	
-	if (is_double_lt(da.data, db.data))
-		return -1;
-	
-	return 1;
-}
-
-int __letf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		// TODO: sigNaNs
-		return 1;
-	}
-	
-	if (is_long_double_eq(ta.data, tb.data))
-		return 0;
-	
-	if (is_long_double_lt(ta.data, tb.data))
-		return -1;
-	
-	return 1;
-}
-
-int __gtsf2(float a, float b)
-{
-	float_t fa;
-	float_t fb;
-	
-	fa.val = a;
-	fb.val = b;
-	
-	if ((is_float_nan(fa.data)) || (is_float_nan(fb.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_float_gt(fa.data, fb.data))
-		return 1;
-	
-	return 0;
-}
-
-int __gtdf2(double a, double b)
-{
-	double_t da;
-	double_t db;
-	
-	da.val = a;
-	db.val = b;
-	
-	if ((is_double_nan(da.data)) || (is_double_nan(db.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_double_gt(da.data, db.data))
-		return 1;
-	
-	return 0;
-}
-
-int __gttf2(long double a, long double b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = a;
-	tb.val = b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data))) {
-		// TODO: sigNaNs
-		return -1;
-	}
-	
-	if (is_long_double_gt(ta.data, tb.data))
-		return 1;
-	
-	return 0;
-}
-
-/* SPARC quadruple-precision wrappers */
-
-void _Qp_add(long double *c, long double *a, long double *b)
-{
-	*c = __addtf3(*a, *b);
-}
-
-void _Qp_sub(long double *c, long double *a, long double *b)
-{
-	*c = __subtf3(*a, *b);
-}
-
-void _Qp_mul(long double *c, long double *a, long double *b)
-{
-	*c = __multf3(*a, *b);
-}
-
-void _Qp_div(long double *c, long double *a, long double *b)
-{
-	*c = __divtf3(*a, *b);
-}
-
-void _Qp_neg(long double *c, long double *a)
-{
-	*c = __negtf2(*a);
-}
-
-void _Qp_stoq(long double *c, float a)
-{
-	*c = __extendsftf2(a);
-}
-
-void _Qp_dtoq(long double *c, double a)
-{
-	*c = __extenddftf2(a);
-}
-
-float _Qp_qtos(long double *a)
-{
-	return __trunctfsf2(*a);
-}
-
-double _Qp_qtod(long double *a)
-{
-	return __trunctfdf2(*a);
-}
-
-int _Qp_qtoi(long double *a)
-{
-	return __fixtfsi(*a);
-}
-
-unsigned int _Qp_qtoui(long double *a)
-{
-	return __fixunstfsi(*a);
-}
-
-long _Qp_qtox(long double *a)
-{
-	return __fixtfdi(*a);
-}
-
-unsigned long _Qp_qtoux(long double *a)
-{
-	return __fixunstfdi(*a);
-}
-
-void _Qp_itoq(long double *c, int a)
-{
-	*c = __floatsitf(a);
-}
-
-void _Qp_uitoq(long double *c, unsigned int a)
-{
-	*c = __floatunsitf(a);
-}
-
-void _Qp_xtoq(long double *c, long a)
-{
-	*c = __floatditf(a);
-}
-
-void _Qp_uxtoq(long double *c, unsigned long a)
-{
-	*c = __floatunditf(a);
-}
-
-int _Qp_cmp(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 3;
-	
-	if (is_long_double_eq(ta.data, tb.data))
-		return 0;
-	
-	if (is_long_double_lt(ta.data, tb.data))
-		return 1;
-	
-	return 2;
-}
-
-int _Qp_cmpe(long double *a, long double *b)
-{
-	/* strange, but is defined this way in SPARC Compliance Definition */
-	return _Qp_cmp(a, b);
-}
-
-int _Qp_feq(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return is_long_double_eq(ta.data, tb.data);
-}
-
-int _Qp_fge(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return is_long_double_eq(ta.data, tb.data) ||
-	    is_long_double_gt(ta.data, tb.data);
-}
-
-int _Qp_fgt(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return is_long_double_gt(ta.data, tb.data);
-}
-
-int _Qp_fle(long double*a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return is_long_double_eq(ta.data, tb.data) ||
-	    is_long_double_lt(ta.data, tb.data);
-}
-
-int _Qp_flt(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return is_long_double_lt(ta.data, tb.data);
-}
-
-int _Qp_fne(long double *a, long double *b)
-{
-	long_double_t ta;
-	long_double_t tb;
-	
-	ta.val = *a;
-	tb.val = *b;
-	
-	if ((is_long_double_nan(ta.data)) || (is_long_double_nan(tb.data)))
-		return 0;
-	
-	return !is_long_double_eq(ta.data, tb.data);
-}
-
-float __aeabi_d2f(double a)
-{
-	return __truncdfsf2(a);
-}
-
-double __aeabi_f2d(float a)
-{
-	return __extendsfdf2(a);
-}
-
-
-float __aeabi_i2f(int i)
-{
-	return __floatsisf(i);
-}
-
-float __aeabi_ui2f(int i)
-{
-	return __floatunsisf(i);
-}
-
-double __aeabi_i2d(int i)
-{
-	return __floatsidf(i);
-}
-
-double __aeabi_ui2d(unsigned int i)
-{
-	return __floatunsidf(i);
-}
-
-double __aeabi_l2d(long long i)
-{
-	return __floattidf(i);
-}
-
-float __aeabi_l2f(long long i)
-{
-	return __floattisf(i);
-}
-
-float __aeabi_ul2f(unsigned long long u)
-{
-	return __floatuntisf(u);
-}
-
-int __aeabi_f2iz(float a)
-{
-	return __fixsfsi(a);
-}
-
-int __aeabi_f2uiz(float a)
-{
-	return __fixunssfsi(a);
-}
-
-int __aeabi_d2iz(double a)
-{
-	return __fixdfsi(a);
-}
-
-unsigned int __aeabi_d2uiz(double a)
-{
-	return __fixunsdfsi(a);
-}
-
-long long __aeabi_d2lz(double a)
-{
-	return __fixdfti(a);
-}
-
-int __aeabi_fcmpge(float a, float b)
-{
-	return __gesf2(a, b);
-}
-
-int __aeabi_fcmpgt(float a, float b)
-{
-	return __gtsf2(a, b);
-}
-
-int __aeabi_fcmplt(float a, float b)
-{
-	return __ltsf2(a, b);
-}
-
-int __aeabi_fcmpeq(float a, float b)
-{
-	return __eqsf2(a, b);
-}
-
-int __aeabi_dcmpge(double a, double b)
-{
-	return __gedf2(a, b);
-}
-
-int __aeabi_dcmpgt(double a, double b)
-{
-	return __gtdf2(a, b);
-}
-
-int __aeabi_dcmplt(double a, double b)
-{
-	return __ltdf2(a, b);
-}
-
-int __aeabi_dcmple(double a, double b)
-{
-	return __ledf2(a, b);
-}
-
-int __aeabi_dcmpeq(double a, double b)
-{
-	return __eqdf2(a, b);
-}
-
-float __aeabi_fadd(float a, float b)
-{
-	return __addsf3(a, b);
-}
-
-float __aeabi_fsub(float a, float b)
-{
-	return __subsf3(a, b);
-}
-
-float __aeabi_fmul(float a, float b)
-{
-	return __mulsf3(a, b);
-}
-
-float __aeabi_fdiv(float a, float b)
-{
-	return __divsf3(a, b);
-}
-
-double __aeabi_dadd(double a, double b)
-{
-	return __adddf3(a, b);
-}
-
-double __aeabi_dsub(double a, double b)
-{
-	return __subdf3(a, b);
-}
-
-double __aeabi_dmul(double a, double b)
-{
-	return __muldf3(a, b);
-}
-
-double __aeabi_ddiv(double a, double b)
-{
-	return __divdf3(a, b);
-}
-
-/** @}
- */
Index: pace/lib/softfloat/softfloat.h
===================================================================
--- uspace/lib/softfloat/softfloat.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ 	(revision )
@@ -1,249 +1,0 @@
-/*
- * Copyright (c) 2005 Josef Cejka
- * Copyright (c) 2011 Petr Koupy
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup softfloat
- * @{
- */
-/** @file Softfloat API.
- */
-
-#ifndef __SOFTFLOAT_H__
-#define __SOFTFLOAT_H__
-
-extern float __addsf3(float, float);
-extern double __adddf3(double, double);
-extern long double __addtf3(long double, long double);
-extern long double __addxf3(long double, long double);
-
-extern float __subsf3(float, float);
-extern double __subdf3(double, double);
-extern long double __subtf3(long double, long double);
-extern long double __subxf3(long double, long double);
-
-extern float __mulsf3(float, float);
-extern double __muldf3(double, double);
-extern long double __multf3(long double, long double);
-extern long double __mulxf3(long double, long double);
-
-extern float __divsf3(float, float);
-extern double __divdf3(double, double);
-extern long double __divtf3(long double, long double);
-extern long double __divxf3(long double, long double);
-
-extern float __negsf2(float);
-extern double __negdf2(double);
-extern long double __negtf2(long double);
-extern long double __negxf2(long double);
-
-extern double __extendsfdf2(float);
-extern long double __extendsftf2(float);
-extern long double __extendsfxf2(float);
-extern long double __extenddftf2(double);
-extern long double __extenddfxf2(double);
-
-extern double __truncxfdf2(long double);
-extern double __trunctfdf2(long double);
-extern float __truncxfsf2(long double);
-extern float __trunctfsf2(long double);
-extern float __truncdfsf2(double);
-
-extern int __fixsfsi(float);
-extern int __fixdfsi(double);
-extern int __fixtfsi(long double);
-extern int __fixxfsi(long double);
-
-extern long __fixsfdi(float);
-extern long __fixdfdi(double);
-extern long __fixtfdi(long double);
-extern long __fixxfdi(long double);
-
-extern long long __fixsfti(float);
-extern long long __fixdfti(double);
-extern long long __fixtfti(long double);
-extern long long __fixxfti(long double);
-
-extern unsigned int __fixunssfsi(float);
-extern unsigned int __fixunsdfsi(double);
-extern unsigned int __fixunstfsi(long double);
-extern unsigned int __fixunsxfsi(long double);
-
-extern unsigned long __fixunssfdi(float);
-extern unsigned long __fixunsdfdi(double);
-extern unsigned long __fixunstfdi(long double);
-extern unsigned long __fixunsxfdi(long double);
-
-extern unsigned long long __fixunssfti(float);
-extern unsigned long long __fixunsdfti(double);
-extern unsigned long long __fixunstfti(long double);
-extern unsigned long long __fixunsxfti(long double);
-
-extern float __floatsisf(int);
-extern double __floatsidf(int);
-extern long double __floatsitf(int);
-extern long double __floatsixf(int);
-
-extern float __floatdisf(long);
-extern double __floatdidf(long);
-extern long double __floatditf(long);
-extern long double __floatdixf(long);
-
-extern float __floattisf(long long);
-extern double __floattidf(long long);
-extern long double __floattitf(long long);
-extern long double __floattixf(long long);
-
-extern float __floatunsisf(unsigned int);
-extern double __floatunsidf(unsigned int);
-extern long double __floatunsitf(unsigned int);
-extern long double __floatunsixf(unsigned int);
-
-extern float __floatundisf(unsigned long);
-extern double __floatundidf(unsigned long);
-extern long double __floatunditf(unsigned long);
-extern long double __floatundixf(unsigned long);
-
-extern float __floatuntisf(unsigned long long);
-extern double __floatuntidf(unsigned long long);
-extern long double __floatuntitf(unsigned long long);
-extern long double __floatuntixf(unsigned long long);
-
-extern int __cmpsf2(float, float);
-extern int __cmpdf2(double, double);
-extern int __cmptf2(long double, long double);
-
-extern int __unordsf2(float, float);
-extern int __unorddf2(double, double);
-extern int __unordtf2(long double, long double);
-
-extern int __eqsf2(float, float);
-extern int __eqdf2(double, double);
-extern int __eqtf2(long double, long double);
-
-extern int __nesf2(float, float);
-extern int __nedf2(double, double);
-extern int __netf2(long double, long double);
-
-extern int __gesf2(float, float);
-extern int __gedf2(double, double);
-extern int __getf2(long double, long double);
-
-extern int __ltsf2(float, float);
-extern int __ltdf2(double, double);
-extern int __lttf2(long double, long double);
-
-extern int __lesf2(float, float);
-extern int __ledf2(double, double);
-extern int __letf2(long double, long double);
-
-extern int __gtsf2(float, float);
-extern int __gtdf2(double, double);
-extern int __gttf2(long double, long double);
-
-/* Not implemented yet */
-extern float __powisf2(float, int);
-extern double __powidf2 (double, int);
-extern long double __powitf2(long double, int);
-extern long double __powixf2(long double, int);
-
-/* SPARC quadruple-precision wrappers */
-extern void _Qp_add(long double *, long double *, long double *);
-extern void _Qp_sub(long double *, long double *, long double *);
-extern void _Qp_mul(long double *, long double *, long double *);
-extern void _Qp_div(long double *, long double *, long double *);
-extern void _Qp_neg(long double *, long double *);
-
-extern void _Qp_stoq(long double *, float);
-extern void _Qp_dtoq(long double *, double);
-extern float _Qp_qtos(long double *);
-extern double _Qp_qtod(long double *);
-
-extern int _Qp_qtoi(long double *);
-extern unsigned int _Qp_qtoui(long double *);
-extern long _Qp_qtox(long double *);
-extern unsigned long _Qp_qtoux(long double *);
-
-extern void _Qp_itoq(long double *, int);
-extern void _Qp_uitoq(long double *, unsigned int);
-extern void _Qp_xtoq(long double *, long);
-extern void _Qp_uxtoq(long double *, unsigned long);
-
-extern int _Qp_cmp(long double *, long double *);
-extern int _Qp_cmpe(long double *, long double *);
-extern int _Qp_feq(long double *, long double *);
-extern int _Qp_fge(long double *, long double *);
-extern int _Qp_fgt(long double *, long double *);
-extern int _Qp_fle(long double*, long double *);
-extern int _Qp_flt(long double *, long double *);
-extern int _Qp_fne(long double *, long double *);
-
-/* ARM EABI */
-extern float __aeabi_d2f(double);
-extern double __aeabi_f2d(float);
-extern float __aeabi_i2f(int);
-extern float __aeabi_ui2f(int);
-extern double __aeabi_i2d(int);
-extern double __aeabi_ui2d(unsigned int);
-extern double __aeabi_l2d(long long);
-extern float __aeabi_l2f(long long);
-extern float __aeabi_ul2f(unsigned long long);
-extern unsigned int __aeabi_d2uiz(double);
-extern long long __aeabi_d2lz(double);
-
-extern int __aeabi_f2iz(float);
-extern int __aeabi_f2uiz(float);
-extern int __aeabi_d2iz(double);
-
-extern int __aeabi_fcmpge(float, float);
-extern int __aeabi_fcmpgt(float, float);
-extern int __aeabi_fcmplt(float, float);
-extern int __aeabi_fcmpeq(float, float);
-
-extern int __aeabi_dcmpge(double, double);
-extern int __aeabi_dcmpgt(double, double);
-extern int __aeabi_dcmplt(double, double);
-extern int __aeabi_dcmple(double, double);
-extern int __aeabi_dcmpeq(double, double);
-
-extern float __aeabi_fadd(float, float);
-extern float __aeabi_fsub(float, float);
-extern float __aeabi_fmul(float, float);
-extern float __aeabi_fdiv(float, float);
-
-extern double __aeabi_dadd(double, double);
-extern double __aeabi_dsub(double, double);
-extern double __aeabi_dmul(double, double);
-extern double __aeabi_ddiv(double, double);
-
-/* Not implemented yet */
-extern void _Qp_sqrt(long double *, long double *);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/softfloat/sub.c
===================================================================
--- uspace/lib/softfloat/sub.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/sub.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -34,8 +34,8 @@
  */
 
-#include "sftypes.h"
 #include "sub.h"
 #include "comparison.h"
 #include "common.h"
+#include "add.h"
 
 /** Subtract two single-precision floats with the same sign.
@@ -438,4 +438,116 @@
 }
 
+#ifdef float32_t
+
+float32_t __subsf3(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		ub.data.parts.sign = !ub.data.parts.sign;
+		res.data = add_float32(ua.data, ub.data);
+	} else
+		res.data = sub_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float32_t __aeabi_fsub(float32_t a, float32_t b)
+{
+	float32_u ua;
+	ua.val = a;
+	
+	float32_u ub;
+	ub.val = b;
+	
+	float32_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		ub.data.parts.sign = !ub.data.parts.sign;
+		res.data = add_float32(ua.data, ub.data);
+	} else
+		res.data = sub_float32(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float64_t
+
+float64_t __subdf3(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		ub.data.parts.sign = !ub.data.parts.sign;
+		res.data = add_float64(ua.data, ub.data);
+	} else
+		res.data = sub_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+float64_t __aeabi_dsub(float64_t a, float64_t b)
+{
+	float64_u ua;
+	ua.val = a;
+	
+	float64_u ub;
+	ub.val = b;
+	
+	float64_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		ub.data.parts.sign = !ub.data.parts.sign;
+		res.data = add_float64(ua.data, ub.data);
+	} else
+		res.data = sub_float64(ua.data, ub.data);
+	
+	return res.val;
+}
+
+#endif
+
+#ifdef float128_t
+
+float128_t __subtf3(float128_t a, float128_t b)
+{
+	float128_u ua;
+	ua.val = a;
+	
+	float128_u ub;
+	ub.val = b;
+	
+	float128_u res;
+	
+	if (ua.data.parts.sign != ub.data.parts.sign) {
+		ub.data.parts.sign = !ub.data.parts.sign;
+		res.data = add_float128(ua.data, ub.data);
+	} else
+		res.data = sub_float128(ua.data, ub.data);
+	
+	return res.val;
+}
+
+void _Qp_sub(float128_t *c, float128_t *a, float128_t *b)
+{
+	*c = __subtf3(*a, *b);
+}
+
+#endif
+
 /** @}
  */
Index: uspace/lib/softfloat/sub.h
===================================================================
--- uspace/lib/softfloat/sub.h	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/softfloat/sub.h	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -37,4 +37,6 @@
 #define __SUB_H__
 
+#include <mathtypes.h>
+
 extern float32 sub_float32(float32, float32);
 extern float64 sub_float64(float64, float64);
@@ -42,4 +44,19 @@
 extern float128 sub_float128(float128, float128);
 
+#ifdef float32_t
+extern float32_t __subsf3(float32_t, float32_t);
+extern float32_t __aeabi_fsub(float32_t, float32_t);
+#endif
+
+#ifdef float64_t
+extern float64_t __subdf3(float64_t, float64_t);
+extern float64_t __aeabi_dsub(float64_t, float64_t);
+#endif
+
+#ifdef float128_t
+extern float128_t __subtf3(float128_t, float128_t);
+extern void _Qp_sub(float128_t *, float128_t *, float128_t *);
+#endif
+
 #endif
 
Index: uspace/lib/usbdev/src/hub.c
===================================================================
--- uspace/lib/usbdev/src/hub.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/lib/usbdev/src/hub.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -229,5 +229,5 @@
 	 * above might use much of this time so we should only wait to fill
 	 * up the 100ms quota*/
-	const suseconds_t elapsed = tv_sub(&end_time, &start_time);
+	const suseconds_t elapsed = tv_sub_diff(&end_time, &start_time);
 	if (elapsed < 100000) {
 		async_usleep(100000 - elapsed);
Index: uspace/srv/audio/hound/audio_device.c
===================================================================
--- uspace/srv/audio/hound/audio_device.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/srv/audio/hound/audio_device.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -279,5 +279,5 @@
 			getuptime(&time2);
 			log_verbose("Time to mix sources: %li\n",
-			    tv_sub(&time2, &time1));
+			    tv_sub_diff(&time2, &time1));
 			break;
 		}
Index: uspace/srv/devman/drv_conn.c
===================================================================
--- uspace/srv/devman/drv_conn.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/srv/devman/drv_conn.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -173,7 +173,7 @@
 	callid = async_get_call(&call);
 	if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) {
-		log_msg(LOG_DEFAULT, LVL_ERROR, 
+		log_msg(LOG_DEFAULT, LVL_ERROR,
 		    "Invalid protocol when trying to receive match id.");
-		async_answer_0(callid, EINVAL); 
+		async_answer_0(callid, EINVAL);
 		delete_match_id(match_id);
 		return EINVAL;
@@ -246,5 +246,5 @@
 	if (ftype != fun_inner && ftype != fun_exposed) {
 		/* Unknown function type */
-		log_msg(LOG_DEFAULT, LVL_ERROR, 
+		log_msg(LOG_DEFAULT, LVL_ERROR,
 		    "Unknown function type %d provided by driver.",
 		    (int) ftype);
@@ -404,5 +404,5 @@
 	fibril_rwlock_read_unlock(&device_tree.rwlock);
 	
-	rc = fun_offline(fun);
+	rc = fun_online(fun);
 	if (rc != EOK) {
 		fun_busy_unlock(fun);
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/srv/devman/fun.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -348,4 +348,5 @@
 		loc_register_tree_function(fun, &device_tree);
 	
+	fun->state = FUN_ON_LINE;
 	fibril_rwlock_write_unlock(&device_tree.rwlock);
 	
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ uspace/srv/hid/compositor/compositor.c	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -90,4 +90,5 @@
 	link_t link;
 	atomic_t ref_cnt;
+	window_flags_t flags;
 	service_id_t in_dsid;
 	service_id_t out_dsid;
@@ -635,4 +636,11 @@
 	sysarg_t pos_id = IPC_GET_ARG1(*icall);
 	sysarg_t grab_flags = IPC_GET_ARG2(*icall);
+	
+	/*
+	 * Filter out resize grab flags if the window
+	 * is not resizeable.
+	 */
+	if ((win->flags & WINDOW_RESIZEABLE) != WINDOW_RESIZEABLE)
+		grab_flags &= ~(GF_RESIZE_X | GF_RESIZE_Y);
 
 	fibril_mutex_lock(&pointer_list_mtx);
@@ -903,4 +911,6 @@
 				return;
 			}
+			
+			win->flags = IPC_GET_ARG1(call);
 
 			char name_in[LOC_NAME_MAXLEN + 1];
@@ -1885,5 +1895,5 @@
 		fibril_mutex_lock(&window_list_mtx);
 		window_t *win = (window_t *) list_first(&window_list);
-		if (win && win->surface) {
+		if ((win) && (win->surface) && (win->flags & WINDOW_RESIZEABLE)) {
 			window_event_t *event = (window_event_t *) malloc(sizeof(window_event_t));
 			if (event == NULL) {
Index: version
===================================================================
--- version	(revision a931b7b2faca447e0708fd5fae0f85116e4c788d)
+++ version	(revision cc575ef99163b3a869a65477f280acca17c5bdd5)
@@ -46,3 +46,3 @@
 
 NAME = Elastic Horse
-COPYRIGHT = Copyright (c) 2001-2014 HelenOS project
+COPYRIGHT = Copyright (c) 2001-2015 HelenOS project
