Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ HelenOS.config	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -582,7 +582,4 @@
 # USB settings
 
-% USB verbose messages
-! CONFIG_USB_VERBOSE (n/y)
-
 % Start virtual USB host controller
 ! CONFIG_RUN_VIRTUAL_USB_HC (n/y)
Index: abi/include/ipc/ipc.h
===================================================================
--- abi/include/ipc/ipc.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ abi/include/ipc/ipc.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -57,9 +57,6 @@
 #define IPC_CALL_FORWARDED  (1 << 2)
 
-/** Identify connect_me_to answer */
-#define IPC_CALL_CONN_ME_TO  (1 << 3)
-
 /** Interrupt notification */
-#define IPC_CALL_NOTIF  (1 << 4)
+#define IPC_CALL_NOTIF  (1 << 3)
 
 
Index: boot/Makefile.common
===================================================================
--- boot/Makefile.common	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ boot/Makefile.common	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -74,5 +74,6 @@
 	$(USPACE_PATH)/srv/locsrv/locsrv \
 	$(USPACE_PATH)/srv/bd/rd/rd \
-	$(USPACE_PATH)/srv/vfs/vfs
+	$(USPACE_PATH)/srv/vfs/vfs \
+	$(USPACE_PATH)/srv/logger/logger
 
 ifeq ($(RDFMT),tmpfs)
@@ -170,8 +171,8 @@
 	$(USPACE_PATH)/app/killall/killall \
 	$(USPACE_PATH)/app/loc/loc \
+	$(USPACE_PATH)/app/logset/logset \
 	$(USPACE_PATH)/app/mkfat/mkfat \
 	$(USPACE_PATH)/app/mkexfat/mkexfat \
 	$(USPACE_PATH)/app/mkmfs/mkmfs \
-	$(USPACE_PATH)/app/lsusb/lsusb \
 	$(USPACE_PATH)/app/sbi/sbi \
 	$(USPACE_PATH)/app/sportdmp/sportdmp \
Index: boot/arch/ppc32/_link.ld.in
===================================================================
--- boot/arch/ppc32/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ boot/arch/ppc32/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -2,5 +2,5 @@
 
 SECTIONS {
-	. = 0x01000000;
+	. = 0x02000000;
 	.text : {
 		*(BOOTSTRAP);
Index: boot/arch/ppc32/include/arch.h
===================================================================
--- boot/arch/ppc32/include/arch.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ boot/arch/ppc32/include/arch.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -35,5 +35,5 @@
 #define BOOT_OFFSET  0x8000
 
-#define LOADER_ADDRESS  0x01000000
+#define LOADER_ADDRESS  0x02000000
 
 #ifndef __ASM__
Index: boot/arch/ppc32/src/main.c
===================================================================
--- boot/arch/ppc32/src/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ boot/arch/ppc32/src/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -103,4 +103,10 @@
 	}
 	
+	if (top >= (size_t) loader_address_pa) {
+		printf("Inflated components overlap loader area.\n");
+		printf("The boot image is too large. Halting.\n");
+		halt();
+	}
+	
 	void *balloc_base;
 	void *balloc_base_pa;
Index: contrib/conf/sparc64-qe
===================================================================
--- contrib/conf/sparc64-qe	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ contrib/conf/sparc64-qe	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+qemu-system-sparc64 $@ -M sun4u -boot d -cdrom image.iso
Index: defaults/amd64/Makefile.config
===================================================================
--- defaults/amd64/Makefile.config	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ defaults/amd64/Makefile.config	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -54,5 +54,5 @@
 
 # Default framebuffer mode
-CONFIG_BFB_MODE = 800x600
+CONFIG_BFB_MODE = 1024x768
 
 # Default framebuffer depth
Index: defaults/ia32/Makefile.config
===================================================================
--- defaults/ia32/Makefile.config	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ defaults/ia32/Makefile.config	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -60,5 +60,5 @@
 
 # Default framebuffer mode
-CONFIG_BFB_MODE = 800x600
+CONFIG_BFB_MODE = 1024x768
 
 # Default framebuffer depth
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -257,4 +257,15 @@
 	generic/src/ipc/ipc.c \
 	generic/src/ipc/sysipc.c \
+	generic/src/ipc/sysipc_ops.c \
+	generic/src/ipc/ops/clnestab.c \
+	generic/src/ipc/ops/conctmeto.c \
+	generic/src/ipc/ops/concttome.c \
+	generic/src/ipc/ops/connclone.c \
+	generic/src/ipc/ops/dataread.c \
+	generic/src/ipc/ops/datawrite.c \
+	generic/src/ipc/ops/debug.c \
+	generic/src/ipc/ops/sharein.c \
+	generic/src/ipc/ops/shareout.c \
+	generic/src/ipc/ops/stchngath.c \
 	generic/src/ipc/ipcrsc.c \
 	generic/src/ipc/irq.c \
Index: kernel/arch/arm32/Makefile.inc
===================================================================
--- kernel/arch/arm32/Makefile.inc	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/arch/arm32/Makefile.inc	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -33,5 +33,5 @@
 ATSIGN = %
 
-GCC_CFLAGS += -march=armv4
+GCC_CFLAGS += -march=armv4 -fno-omit-frame-pointer -mapcs-frame
 
 BITS = 32
Index: kernel/arch/arm32/include/istate.h
===================================================================
--- kernel/arch/arm32/include/istate.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/arch/arm32/include/istate.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -49,4 +49,5 @@
 /** Struct representing CPU state saved when an exception occurs. */
 typedef struct istate {
+	uint32_t dummy;
 	uint32_t spsr;
 	uint32_t sp;
Index: kernel/arch/arm32/src/exc_handler.S
===================================================================
--- kernel/arch/arm32/src/exc_handler.S	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/arch/arm32/src/exc_handler.S	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -130,7 +130,9 @@
 	stmfd r13!, {r2}
 2:
+	sub sp, sp, #4
 .endm
 
 .macro LOAD_REGS_FROM_STACK
+	add sp, sp, #4
 	ldmfd r13!, {r0}
 	msr spsr, r0
Index: kernel/arch/arm32/src/exception.c
===================================================================
--- kernel/arch/arm32/src/exception.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/arch/arm32/src/exception.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -123,5 +123,5 @@
 	
 	asm volatile (
-		"mrc p15, 0, %[control_reg], c1, c1"
+		"mrc p15, 0, %[control_reg], c1, c0"
 		: [control_reg] "=r" (control_reg)
 	);
@@ -131,5 +131,5 @@
 	
 	asm volatile (
-		"mcr p15, 0, %[control_reg], c1, c1"
+		"mcr p15, 0, %[control_reg], c1, c0"
 		:: [control_reg] "r" (control_reg)
 	);
Index: kernel/arch/arm32/src/mm/page_fault.c
===================================================================
--- kernel/arch/arm32/src/mm/page_fault.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/arch/arm32/src/mm/page_fault.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -77,49 +77,4 @@
 }
 
-/** Decides whether the instruction is load/store or not.
- *
- * @param instr Instruction
- *
- * @return true when instruction is load/store, false otherwise
- *
- */
-static inline bool is_load_store_instruction(instruction_t instr)
-{
-	/* load store immediate offset */
-	if (instr.type == 0x2)
-		return true;
-	
-	/* load store register offset */
-	if ((instr.type == 0x3) && (instr.bit4 == 0))
-		return true;
-	
-	/* load store multiple */
-	if (instr.type == 0x4)
-		return true;
-	
-	/* oprocessor load/store */
-	if (instr.type == 0x6)
-		return true;
-	
-	return false;
-}
-
-/** Decides whether the instruction is swap or not.
- *
- * @param instr Instruction
- *
- * @return true when instruction is swap, false otherwise
- */
-static inline bool is_swap_instruction(instruction_t instr)
-{
-	/* swap, swapb instruction */
-	if ((instr.type == 0x0) &&
-	    ((instr.opcode == 0x8) || (instr.opcode == 0xa)) &&
-	    (instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1))
-		return true;
-	
-	return false;
-}
-
 /** Decides whether read or write into memory is requested.
  *
@@ -128,5 +83,5 @@
  *
  * @return Type of access into memory, PF_ACCESS_EXEC if no memory access is
- * 	   requested.
+ *	   requested.
  */
 static pf_access_t get_memory_access_type(uint32_t instr_addr,
@@ -146,23 +101,38 @@
 	}
 
-	/* load store instructions */
-	if (is_load_store_instruction(instr)) {
-		if (instr.access == 1) {
-			return PF_ACCESS_READ;
-		} else {
-			return PF_ACCESS_WRITE;
+	/* See ARM Architecture reference manual ARMv7-A and ARMV7-R edition
+	 * A5.3 (PDF p. 206) */
+	static const struct {
+		uint32_t mask;
+		uint32_t value;
+		pf_access_t access;
+	} ls_inst[] = {
+		/* Store word/byte */
+		{ 0x0e100000, 0x04000000, PF_ACCESS_WRITE }, /*STR(B) imm*/
+		{ 0x0e100010, 0x06000000, PF_ACCESS_WRITE }, /*STR(B) reg*/
+		/* Load word/byte */
+		{ 0x0e100000, 0x04100000, PF_ACCESS_READ }, /*LDR(B) imm*/
+		{ 0x0e100010, 0x06100000, PF_ACCESS_READ }, /*LDR(B) reg*/
+		/* Store half-word/dual  A5.2.8 */
+		{ 0x0e1000b0, 0x000000b0, PF_ACCESS_WRITE }, /*STRH imm reg*/
+		/* Load half-word/dual A5.2.8 */
+		{ 0x0e0000f0, 0x000000d0, PF_ACCESS_READ }, /*LDRH imm reg*/
+		{ 0x0e1000b0, 0x001000b0, PF_ACCESS_READ }, /*LDRH imm reg*/
+		/* Block data transfer, Store */
+		{ 0x0e100000, 0x08000000, PF_ACCESS_WRITE }, /* STM variants */
+		{ 0x0e100000, 0x08100000, PF_ACCESS_READ },  /* LDM variants */
+		/* Swap */
+		{ 0x0fb00000, 0x01000000, PF_ACCESS_WRITE },
+	};
+	const uint32_t inst = *(uint32_t*)instr_addr;
+	for (unsigned i = 0; i < sizeof(ls_inst) / sizeof(ls_inst[0]); ++i) {
+		if ((inst & ls_inst[i].mask) == ls_inst[i].value) {
+			return ls_inst[i].access;
 		}
-	}
-
-	/* swap, swpb instruction */
-	if (is_swap_instruction(instr)) {
-		return PF_ACCESS_WRITE;
 	}
 
 	panic("page_fault - instruction doesn't access memory "
 	    "(instr_code: %#0" PRIx32 ", badvaddr:%p).",
-	    instr_union.pc, (void *) badvaddr);
-
-	return PF_ACCESS_EXEC;
+	    inst, (void *) badvaddr);
 }
 
Index: kernel/genarch/include/drivers/arm926_uart/arm926_uart.h
===================================================================
--- kernel/genarch/include/drivers/arm926_uart/arm926_uart.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/genarch/include/drivers/arm926_uart/arm926_uart.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -35,6 +35,6 @@
  */
 
-#ifndef KERN_S3C24XX_UART_H_
-#define KERN_S3C24XX_UART_H_
+#ifndef KERN_ARM926_UART_H_
+#define KERN_ARM926_UART_H_
 
 #include <ddi/irq.h>
Index: kernel/genarch/include/multiboot/multiboot.h
===================================================================
--- kernel/genarch/include/multiboot/multiboot.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/genarch/include/multiboot/multiboot.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -99,4 +99,5 @@
 
 extern void multiboot_extract_command(char *, size_t, const char *);
+extern void multiboot_extract_argument(char *, size_t, const char *);
 extern void multiboot_info_parse(uint32_t, const multiboot_info_t *);
 
Index: kernel/genarch/src/drivers/arm926_uart/arm926_uart.c
===================================================================
--- kernel/genarch/src/drivers/arm926_uart/arm926_uart.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/genarch/src/drivers/arm926_uart/arm926_uart.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -83,5 +83,5 @@
 	arm926_uart_t *uart = irq->instance;
 
-	// TODO make pio_read accept consts pointers and remove the cast
+	// TODO make pio_read accept const pointers and remove the cast
 	while ((pio_read_32((ioport32_t*)&uart->regs->flag) & ARM926_UART_FLAG_RXFE_FLAG) == 0) {
 		/* We ignore all error flags here */
@@ -109,5 +109,5 @@
 
 	/* Mask all interrupts */
-	uart->regs->interrupt_mask = ARM926_UART_INTERRUPT_ALL;
+	uart->regs->interrupt_mask = 0;
 
 	outdev_initialize("arm926_uart_dev", &uart->outdev, &arm926_uart_ops);
@@ -133,5 +133,5 @@
 	irq_register(&uart->irq);
 	/* Enable receive interrupt */
-	uart->regs->interrupt_mask &= ~ARM926_UART_INTERRUPT_RX_FLAG;
+	uart->regs->interrupt_mask |= ARM926_UART_INTERRUPT_RX_FLAG;
 }
 
Index: kernel/genarch/src/multiboot/multiboot.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/genarch/src/multiboot/multiboot.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -71,4 +71,33 @@
 }
 
+/** Extract arguments from the multiboot module command line.
+ *
+ * @param buf      Destination buffer (will be always NULL-terminated).
+ * @param size     Size of destination buffer (in bytes).
+ * @param cmd_line Input string (the command line).
+ *
+ */
+void multiboot_extract_argument(char *buf, size_t size, const char *cmd_line)
+{
+	/* Start after first space. */
+	const char *start = str_chr(cmd_line, ' ');
+	if (start == NULL) {
+		str_cpy(buf, size, "");
+		return;
+	}
+
+	const char *end = cmd_line + str_size(cmd_line);
+
+	/* Skip the space(s). */
+	while (start != end) {
+		if (start[0] == ' ')
+			start++;
+		else
+			break;
+	}
+
+	str_ncpy(buf, size, start, (size_t) (end - start));
+}
+
 static void multiboot_modules(uint32_t count, multiboot_module_t *mods)
 {
@@ -84,6 +113,10 @@
 			multiboot_extract_command(init.tasks[init.cnt].name,
 			    CONFIG_TASK_NAME_BUFLEN, MULTIBOOT_PTR(mods[i].string));
-		} else
+			multiboot_extract_argument(init.tasks[init.cnt].arguments,
+			    CONFIG_TASK_ARGUMENTS_BUFLEN, MULTIBOOT_PTR(mods[i].string));
+		} else {
 			init.tasks[init.cnt].name[0] = 0;
+			init.tasks[init.cnt].arguments[0] = 0;
+		}
 		
 		init.cnt++;
Index: kernel/genarch/src/multiboot/multiboot2.c
===================================================================
--- kernel/genarch/src/multiboot/multiboot2.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/genarch/src/multiboot/multiboot2.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -49,4 +49,6 @@
 		multiboot_extract_command(init.tasks[init.cnt].name,
 		    CONFIG_TASK_NAME_BUFLEN, module->string);
+		multiboot_extract_argument(init.tasks[init.cnt].arguments,
+		    CONFIG_TASK_ARGUMENTS_BUFLEN, module->string);
 		
 		init.cnt++;
Index: kernel/generic/include/config.h
===================================================================
--- kernel/generic/include/config.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/include/config.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -47,4 +47,11 @@
 #define CONFIG_INIT_TASKS        32
 #define CONFIG_TASK_NAME_BUFLEN  32
+#define CONFIG_TASK_ARGUMENTS_BUFLEN 64
+
+/**
+ * Maximum buffer size allowed for IPC_M_DATA_WRITE and IPC_M_DATA_READ
+ * requests.
+ */
+#define DATA_XFER_LIMIT  (64 * 1024)
 
 #ifndef __ASM__
@@ -56,4 +63,5 @@
 	size_t size;
 	char name[CONFIG_TASK_NAME_BUFLEN];
+	char arguments[CONFIG_TASK_ARGUMENTS_BUFLEN];
 } init_task_t;
 
Index: kernel/generic/include/ipc/ipc.h
===================================================================
--- kernel/generic/include/ipc/ipc.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/include/ipc/ipc.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -65,4 +65,5 @@
 	mutex_t lock;
 	link_t link;
+	struct task *caller;
 	struct answerbox *callee;
 	ipc_phone_state_t state;
@@ -72,4 +73,7 @@
 typedef struct answerbox {
 	IRQ_SPINLOCK_DECLARE(lock);
+
+	/** Answerbox is active until it enters cleanup. */
+	bool active;
 	
 	struct task *task;
@@ -106,10 +110,43 @@
 
 typedef struct {
-	link_t link;
+	/**
+	 * Task link.
+	 * Valid only when the call is not forgotten.
+	 * Protected by the task's active_calls_lock.
+	 */
+	link_t ta_link;
+
+	atomic_t refcnt;
+
+	/** Answerbox link. */
+	link_t ab_link;
 	
 	unsigned int flags;
+
+	/** Protects the forget member. */
+	SPINLOCK_DECLARE(forget_lock);
+
+	/**
+	 * True if the caller 'forgot' this call and donated it to the callee.
+	 * Forgotten calls are discarded upon answering (the answer is not
+	 * delivered) and answered calls cannot be forgotten. Forgotten calls
+	 * also do not figure on the task's active call list.
+	 *
+	 * We keep this separate from the flags so that it is not necessary
+	 * to take a lock when accessing them.
+	 */
+	bool forget;
+
+	/** True if the call is in the active list. */
+	bool active;
 	
-	/** Identification of the caller. */
+	/**
+	 * Identification of the caller.
+	 * Valid only when the call is not forgotten.
+	 */
 	struct task *sender;
+	
+	/** Phone which was used to send the call. */
+	phone_t *caller_phone;
 	
 	/** Private data to internal IPC. */
@@ -118,14 +155,10 @@
 	/** Data passed from/to userspace. */
 	ipc_data_t data;
-	
+
+	/** Method as it was sent in the request. */
+	sysarg_t request_method;
+
 	/** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */
 	uint8_t *buffer;
-	
-	/*
-	 * The forward operation can masquerade the caller phone. For those
-	 * cases, we must keep it aside so that the answer is processed
-	 * correctly.
-	 */
-	phone_t *caller_phone;
 } call_t;
 
@@ -136,4 +169,6 @@
 extern call_t *ipc_call_alloc(unsigned int);
 extern void ipc_call_free(call_t *);
+extern void ipc_call_hold(call_t *);
+extern void ipc_call_release(call_t *);
 
 extern int ipc_call(phone_t *, call_t *);
@@ -141,7 +176,8 @@
 extern int ipc_forward(call_t *, phone_t *, answerbox_t *, unsigned int);
 extern void ipc_answer(answerbox_t *, call_t *);
+extern void _ipc_answer_free_call(call_t *, bool);
 
-extern void ipc_phone_init(phone_t *);
-extern void ipc_phone_connect(phone_t *, answerbox_t *);
+extern void ipc_phone_init(phone_t *, struct task *);
+extern bool ipc_phone_connect(phone_t *, answerbox_t *);
 extern int ipc_phone_hangup(phone_t *);
 
@@ -151,5 +187,5 @@
 extern void ipc_backsend_err(phone_t *, call_t *, sysarg_t);
 extern void ipc_answerbox_slam_phones(answerbox_t *, bool);
-extern void ipc_cleanup_call_list(list_t *);
+extern void ipc_cleanup_call_list(answerbox_t *, list_t *);
 
 extern void ipc_print_task(task_id_t);
Index: kernel/generic/include/ipc/ipcrsc.h
===================================================================
--- kernel/generic/include/ipc/ipcrsc.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/include/ipc/ipcrsc.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -40,6 +40,7 @@
 
 extern call_t *get_call(sysarg_t);
+extern int phone_get(sysarg_t, phone_t **);
 extern int phone_alloc(task_t *);
-extern void phone_connect(int, answerbox_t *);
+extern bool phone_connect(int, answerbox_t *);
 extern void phone_dealloc(int);
 
Index: kernel/generic/include/ipc/sysipc_ops.h
===================================================================
--- kernel/generic/include/ipc/sysipc_ops.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/include/ipc/sysipc_ops.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_SYSIPC_OPS_H_
+#define KERN_SYSIPC_OPS_H_
+
+#include <ipc/ipc.h>
+
+typedef struct {
+	/**
+	 * This callback is called from request_preprocess().
+	 * 
+	 * Context:		caller
+	 * Caller alive:	guaranteed
+	 * Races with:		N/A
+	 * Invoked on:		all calls
+	 */
+	int (* request_preprocess)(call_t *, phone_t *);
+
+	/**
+	 * This callback is called when the IPC cleanup code wins the race to
+	 * forget the call.
+	 *
+	 * Context:		caller
+	 * Caller alive:	guaranteed
+	 * Races with:		request_process(), answer_cleanup(),
+	 *			_ipc_answer_free_call()
+	 * Invoked on:		all forgotten calls
+	 */	
+	void (* request_forget)(call_t *);
+
+	/**
+	 * This callback is called from process_request().
+	 *
+	 * Context:		callee
+	 * Caller alive:	no guarantee
+	 * Races with:		request_forget()
+	 * Invoked on:		calls that are received by the callee
+	 */	
+	int (* request_process)(call_t *, answerbox_t *);
+
+	/**
+	 * This callback is called when answer_preprocess() loses the race to
+	 * answer the call.
+	 *
+	 * Context:		callee
+	 * Caller alive:	no guarantee
+	 * Races with:		request_forget()
+	 * Invoked on:		all forgotten calls
+	 */
+	void (* answer_cleanup)(call_t *, ipc_data_t *);
+
+	/**
+	 * This callback is called when answer_preprocess() wins the race to
+	 * answer the call.
+	 *
+	 * Context:		callee
+	 * Caller alive:	guaranteed
+	 * Races with:		N/A
+	 * Invoked on:		all answered calls
+	 */
+	int (* answer_preprocess)(call_t *, ipc_data_t *);
+
+	/**
+	 * This callback is called from process_answer().
+	 *
+	 * Context:		caller
+	 * Caller alive:	guaranteed
+	 * Races with:		N/A
+	 * Invoked on:		all answered calls
+	 */
+	int (* answer_process)(call_t *);
+} sysipc_ops_t;
+
+extern sysipc_ops_t *sysipc_ops_get(sysarg_t);
+
+extern int null_request_preprocess(call_t *, phone_t *);
+extern void null_request_forget(call_t *);
+extern int null_request_process(call_t *, answerbox_t *);
+extern void null_answer_cleanup(call_t *, ipc_data_t *);
+extern int null_answer_preprocess(call_t *, ipc_data_t *);
+extern int null_answer_process(call_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/ipc/sysipc_priv.h
===================================================================
--- kernel/generic/include/ipc/sysipc_priv.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/include/ipc/sysipc_priv.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_SYSIPC_PRIV_H_
+#define KERN_SYSIPC_PRIV_H_
+
+#include <ipc/ipc.h>
+
+extern int answer_preprocess(call_t *, ipc_data_t *);
+
+#endif
+
+/** @}
+ */
Index: kernel/generic/include/lib/elf_load.h
===================================================================
--- kernel/generic/include/lib/elf_load.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/include/lib/elf_load.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -42,16 +42,15 @@
  * ELF error return codes
  */
-#define EE_OK			0	/* No error */
-#define EE_INVALID		1	/* Invalid ELF image */
-#define	EE_MEMORY		2	/* Cannot allocate address space */
-#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
-#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
-#define EE_LOADER		5	/* The image is actually a program loader. */
-#define EE_IRRECOVERABLE	6
+#define EE_OK             0  /* No error */
+#define EE_INVALID        1  /* Invalid ELF image */
+#define EE_MEMORY         2  /* Cannot allocate address space */
+#define EE_INCOMPATIBLE   3  /* ELF image is not compatible with current architecture */
+#define EE_UNSUPPORTED    4  /* Non-supported ELF (e.g. dynamic ELFs) */
+#define EE_LOADER         5  /* The image is actually a program loader. */
+#define EE_IRRECOVERABLE  6  /* Irrecoverable error. */
 
 /**
  * This flags is passed when running the loader, otherwise elf_load()
  * would return with a EE_LOADER error code.
- *
  */
 #define ELD_F_NONE    0
Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/include/proc/task.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -91,8 +91,24 @@
 	
 	/* IPC stuff */
-	answerbox_t answerbox;  /**< Communication endpoint */
+
+	/** Receiving communication endpoint */
+	answerbox_t answerbox;
+
+	/** Sending communication endpoints */
 	phone_t phones[IPC_MAX_PHONES];
-	stats_ipc_t ipc_info;   /**< IPC statistics */
+
+	/** Spinlock protecting the active_calls list. */
+	SPINLOCK_DECLARE(active_calls_lock);
+
+	/**
+	 * List of all calls sent by this task that have not yet been
+	 * answered.
+	 */
+	list_t active_calls;
+
 	event_t events[EVENT_TASK_END - EVENT_END];
+
+	/** IPC statistics */
+	stats_ipc_t ipc_info;
 	
 #ifdef CONFIG_UDEBUG
Index: kernel/generic/src/ipc/event.c
===================================================================
--- kernel/generic/src/ipc/event.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/event.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -163,9 +163,13 @@
 				call->data.task_id = TASK ? TASK->taskid : 0;
 				
-				irq_spinlock_lock(&event->answerbox->irq_lock, true);
-				list_append(&call->link, &event->answerbox->irq_notifs);
-				irq_spinlock_unlock(&event->answerbox->irq_lock, true);
-				
-				waitq_wakeup(&event->answerbox->wq, WAKEUP_FIRST);
+				irq_spinlock_lock(&event->answerbox->irq_lock,
+				    true);
+				list_append(&call->ab_link,
+				    &event->answerbox->irq_notifs);
+				irq_spinlock_unlock(&event->answerbox->irq_lock,
+				    true);
+				
+				waitq_wakeup(&event->answerbox->wq,
+				    WAKEUP_FIRST);
 				
 				if (mask)
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/ipc.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -45,4 +45,6 @@
 #include <ipc/kbox.h>
 #include <ipc/event.h>
+#include <ipc/sysipc_ops.h>
+#include <ipc/sysipc_priv.h>
 #include <errno.h>
 #include <mm/slab.h>
@@ -71,6 +73,23 @@
 {
 	memsetb(call, sizeof(*call), 0);
-	call->sender = TASK;
+	spinlock_initialize(&call->forget_lock, "forget_lock");
+	call->active = false;
+	call->forget = false;
+	call->sender = NULL;
 	call->buffer = NULL;
+}
+
+void ipc_call_hold(call_t *call)
+{
+	atomic_inc(&call->refcnt);
+}
+
+void ipc_call_release(call_t *call)
+{
+	if (atomic_predec(&call->refcnt) == 0) {
+		if (call->buffer)
+			free(call->buffer);
+		slab_free(ipc_call_slab, call);
+	}
 }
 
@@ -83,5 +102,5 @@
  *
  * @return If flags permit it, return NULL, or initialized kernel
- *         call structure.
+ *         call structure with one reference.
  *
  */
@@ -89,6 +108,8 @@
 {
 	call_t *call = slab_alloc(ipc_call_slab, flags);
-	if (call)
+	if (call) {
 		_ipc_call_init(call);
+		ipc_call_hold(call);
+	}
 	
 	return call;
@@ -102,8 +123,5 @@
 void ipc_call_free(call_t *call)
 {
-	/* Check to see if we have data in the IPC_M_DATA_SEND buffer. */
-	if (call->buffer)
-		free(call->buffer);
-	slab_free(ipc_call_slab, call);
+	ipc_call_release(call);
 }
 
@@ -132,18 +150,24 @@
  * @param phone Initialized phone structure.
  * @param box   Initialized answerbox structure.
- *
- */
-void ipc_phone_connect(phone_t *phone, answerbox_t *box)
-{
+ * @return      True if the phone was connected, false otherwise.
+ */
+bool ipc_phone_connect(phone_t *phone, answerbox_t *box)
+{
+	bool active;
+
 	mutex_lock(&phone->lock);
-	
-	phone->state = IPC_PHONE_CONNECTED;
-	phone->callee = box;
-	
 	irq_spinlock_lock(&box->lock, true);
-	list_append(&phone->link, &box->connected_phones);
+
+	active = box->active;
+	if (active) {
+		phone->state = IPC_PHONE_CONNECTED;
+		phone->callee = box;
+		list_append(&phone->link, &box->connected_phones);
+	}
+
 	irq_spinlock_unlock(&box->lock, true);
-	
 	mutex_unlock(&phone->lock);
+
+	return active;
 }
 
@@ -151,9 +175,11 @@
  *
  * @param phone Phone structure to be initialized.
- *
- */
-void ipc_phone_init(phone_t *phone)
+ * @param caller Owning task.
+ *
+ */
+void ipc_phone_init(phone_t *phone, task_t *caller)
 {
 	mutex_initialize(&phone->lock, MUTEX_PASSIVE);
+	phone->caller = caller;
 	phone->callee = NULL;
 	phone->state = IPC_PHONE_FREE;
@@ -167,23 +193,36 @@
  *
  */
-static void _ipc_answer_free_call(call_t *call, bool selflocked)
-{
-	answerbox_t *callerbox = &call->sender->answerbox;
-	bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
-	
+void _ipc_answer_free_call(call_t *call, bool selflocked)
+{
 	/* Count sent answer */
 	irq_spinlock_lock(&TASK->lock, true);
 	TASK->ipc_info.answer_sent++;
 	irq_spinlock_unlock(&TASK->lock, true);
+
+	spinlock_lock(&call->forget_lock);
+	if (call->forget) {
+		/* This is a forgotten call and call->sender is not valid. */
+		spinlock_unlock(&call->forget_lock);
+		ipc_call_free(call);
+		return;
+	} else {
+		/*
+		 * If the call is still active, i.e. it was answered
+		 * in a non-standard way, remove the call from the
+		 * sender's active call list.
+		 */
+		if (call->active) {
+			spinlock_lock(&call->sender->active_calls_lock);
+			list_remove(&call->ta_link);
+			spinlock_unlock(&call->sender->active_calls_lock);
+		}
+	}
+	spinlock_unlock(&call->forget_lock);
+
+	answerbox_t *callerbox = &call->sender->answerbox;
+	bool do_lock = ((!selflocked) || (callerbox != &TASK->answerbox));
 	
 	call->flags |= IPC_CALL_ANSWERED;
 	
-	if (call->flags & IPC_CALL_FORWARDED) {
-		if (call->caller_phone) {
-			/* Demasquerade the caller phone. */
-			call->data.phone = call->caller_phone;
-		}
-	}
-
 	call->data.task_id = TASK->taskid;
 	
@@ -191,5 +230,5 @@
 		irq_spinlock_lock(&callerbox->lock, true);
 	
-	list_append(&call->link, &callerbox->answers);
+	list_append(&call->ab_link, &callerbox->answers);
 	
 	if (do_lock)
@@ -209,5 +248,5 @@
 	/* Remove from active box */
 	irq_spinlock_lock(&box->lock, true);
-	list_remove(&call->link);
+	list_remove(&call->ab_link);
 	irq_spinlock_unlock(&box->lock, true);
 	
@@ -228,6 +267,17 @@
 void ipc_backsend_err(phone_t *phone, call_t *call, sysarg_t err)
 {
+	task_t *caller = phone->caller;
+
+	atomic_inc(&phone->active_calls);
+	call->caller_phone = phone;
+	call->sender = caller;
+
+	call->active = true;
+	spinlock_lock(&caller->active_calls_lock);
+	list_append(&call->ta_link, &caller->active_calls);
+	spinlock_unlock(&caller->active_calls_lock);
+
 	call->data.phone = phone;
-	atomic_inc(&phone->active_calls);
+
 	IPC_SET_RETVAL(call->data, err);
 	_ipc_answer_free_call(call, false);
@@ -243,17 +293,27 @@
 static void _ipc_call(phone_t *phone, answerbox_t *box, call_t *call)
 {
+	task_t *caller = phone->caller;
+
 	/* Count sent ipc call */
-	irq_spinlock_lock(&TASK->lock, true);
-	TASK->ipc_info.call_sent++;
-	irq_spinlock_unlock(&TASK->lock, true);
+	irq_spinlock_lock(&caller->lock, true);
+	caller->ipc_info.call_sent++;
+	irq_spinlock_unlock(&caller->lock, true);
 	
 	if (!(call->flags & IPC_CALL_FORWARDED)) {
 		atomic_inc(&phone->active_calls);
+		call->caller_phone = phone;
+		call->sender = caller;
+
+		call->active = true;
+		spinlock_lock(&caller->active_calls_lock);
+		list_append(&call->ta_link, &caller->active_calls);
+		spinlock_unlock(&caller->active_calls_lock);
+
 		call->data.phone = phone;
-		call->data.task_id = TASK->taskid;
+		call->data.task_id = caller->taskid;
 	}
 	
 	irq_spinlock_lock(&box->lock, true);
-	list_append(&call->link, &box->calls);
+	list_append(&call->ab_link, &box->calls);
 	irq_spinlock_unlock(&box->lock, true);
 	
@@ -275,8 +335,5 @@
 	if (phone->state != IPC_PHONE_CONNECTED) {
 		mutex_unlock(&phone->lock);
-		if (call->flags & IPC_CALL_FORWARDED) {
-			IPC_SET_RETVAL(call->data, EFORWARD);
-			_ipc_answer_free_call(call, false);
-		} else {
+		if (!(call->flags & IPC_CALL_FORWARDED)) {
 			if (phone->state == IPC_PHONE_HUNGUP)
 				ipc_backsend_err(phone, call, EHANGUP);
@@ -325,4 +382,5 @@
 		call_t *call = ipc_call_alloc(0);
 		IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
+		call->request_method = IPC_M_PHONE_HUNGUP;
 		call->flags |= IPC_CALL_DISCARD_ANSWER;
 		_ipc_call(phone, box, call);
@@ -356,10 +414,8 @@
 	TASK->ipc_info.forwarded++;
 	irq_spinlock_pass(&TASK->lock, &oldbox->lock);
-	list_remove(&call->link);
+	list_remove(&call->ab_link);
 	irq_spinlock_unlock(&oldbox->lock, true);
 	
 	if (mode & IPC_FF_ROUTE_FROM_ME) {
-		if (!call->caller_phone)
-			call->caller_phone = call->data.phone;
 		call->data.phone = newphone;
 		call->data.task_id = TASK->taskid;
@@ -406,6 +462,6 @@
 		
 		request = list_get_instance(list_first(&box->irq_notifs),
-		    call_t, link);
-		list_remove(&request->link);
+		    call_t, ab_link);
+		list_remove(&request->ab_link);
 		
 		irq_spinlock_unlock(&box->irq_lock, false);
@@ -416,7 +472,7 @@
 		/* Handle asynchronous answers */
 		request = list_get_instance(list_first(&box->answers),
-		    call_t, link);
-		list_remove(&request->link);
-		atomic_dec(&request->data.phone->active_calls);
+		    call_t, ab_link);
+		list_remove(&request->ab_link);
+		atomic_dec(&request->caller_phone->active_calls);
 	} else if (!list_empty(&box->calls)) {
 		/* Count received call */
@@ -425,9 +481,9 @@
 		/* Handle requests */
 		request = list_get_instance(list_first(&box->calls),
-		    call_t, link);
-		list_remove(&request->link);
+		    call_t, ab_link);
+		list_remove(&request->ab_link);
 		
 		/* Append request to dispatch queue */
-		list_append(&request->link, &box->dispatched_calls);
+		list_append(&request->ab_link, &box->dispatched_calls);
 	} else {
 		/* This can happen regularly after ipc_cleanup */
@@ -449,19 +505,26 @@
 /** Answer all calls from list with EHANGUP answer.
  *
+ * @param box Answerbox with the list.
  * @param lst Head of the list to be cleaned up.
- *
- */
-void ipc_cleanup_call_list(list_t *lst)
-{
+ */
+void ipc_cleanup_call_list(answerbox_t *box, list_t *lst)
+{
+	irq_spinlock_lock(&box->lock, true);
 	while (!list_empty(lst)) {
-		call_t *call = list_get_instance(list_first(lst), call_t, link);
-		if (call->buffer)
-			free(call->buffer);
-		
-		list_remove(&call->link);
-		
+		call_t *call = list_get_instance(list_first(lst), call_t,
+		    ab_link);
+		
+		list_remove(&call->ab_link);
+
+		irq_spinlock_unlock(&box->lock, true);
+
+		ipc_data_t old = call->data;
 		IPC_SET_RETVAL(call->data, EHANGUP);
+		answer_preprocess(call, &old);
 		_ipc_answer_free_call(call, true);
-	}
+
+		irq_spinlock_lock(&box->lock, true);
+	}
+	irq_spinlock_unlock(&box->lock, true);
 }
 
@@ -501,5 +564,7 @@
 			mutex_unlock(&phone->lock);
 			irq_spinlock_unlock(&box->lock, true);
-			
+
+			// FIXME: phone can become deallocated at any time now
+
 			/*
 			 * Send one message to the answerbox for each
@@ -509,4 +574,5 @@
 			 */
 			IPC_SET_IMETHOD(call->data, IPC_M_PHONE_HUNGUP);
+			call->request_method = IPC_M_PHONE_HUNGUP;
 			call->flags |= IPC_CALL_DISCARD_ANSWER;
 			_ipc_call(phone, box, call);
@@ -529,4 +595,126 @@
 }
 
+static void ipc_forget_all_active_calls(void)
+{
+	call_t *call;
+
+restart:
+	spinlock_lock(&TASK->active_calls_lock);
+	if (list_empty(&TASK->active_calls)) {
+		/*
+		 * We are done, there are no more active calls.
+		 * Nota bene: there may still be answers waiting for pick up.
+		 */
+		spinlock_unlock(&TASK->active_calls_lock);	
+		return;	
+	}
+	
+	call = list_get_instance(list_first(&TASK->active_calls), call_t,
+	    ta_link);
+
+	if (!spinlock_trylock(&call->forget_lock)) {
+		/*
+		 * Avoid deadlock and let async_answer() or
+		 *  _ipc_answer_free_call() win the race to dequeue the first
+		 * call on the list.
+		 */
+		spinlock_unlock(&TASK->active_calls_lock);	
+		goto restart;
+	}
+
+	/*
+	 * Forget the call and donate it to the task which holds up the answer.
+	 */
+
+	call->forget = true;
+	call->sender = NULL;
+	list_remove(&call->ta_link);
+
+	/*
+	 * The call may be freed by _ipc_answer_free_call() before we are done
+	 * with it; to avoid working with a destroyed call_t structure, we
+	 * must hold a reference to it.
+	 */
+	ipc_call_hold(call);
+
+	spinlock_unlock(&call->forget_lock);
+	spinlock_unlock(&TASK->active_calls_lock);
+
+	atomic_dec(&call->caller_phone->active_calls);
+
+	sysipc_ops_t *ops = sysipc_ops_get(call->request_method);
+	if (ops->request_forget)
+		ops->request_forget(call);
+
+	ipc_call_release(call);
+
+	goto restart;
+}
+
+/** Wait for all answers to asynchronous calls to arrive. */
+static void ipc_wait_for_all_answered_calls(void)
+{
+	call_t *call;
+	size_t i;
+
+restart:
+	/*
+	 * Go through all phones, until they are all free.
+	 * Locking is needed as there may be connection handshakes in progress.
+	 */
+	for (i = 0; i < IPC_MAX_PHONES; i++) {
+		phone_t *phone = &TASK->phones[i];
+
+		mutex_lock(&phone->lock);	
+		if ((phone->state == IPC_PHONE_HUNGUP) &&
+		    (atomic_get(&phone->active_calls) == 0)) {
+			phone->state = IPC_PHONE_FREE;
+			phone->callee = NULL;
+		}
+
+		/*
+		 * We might have had some IPC_PHONE_CONNECTING phones at the
+		 * beginning of ipc_cleanup(). Depending on whether these were
+		 * forgotten or answered, they will eventually enter the
+		 * IPC_PHONE_FREE or IPC_PHONE_CONNECTED states, respectively.
+		 * In the latter case, the other side may slam the open phones
+		 * at any time, in which case we will get an IPC_PHONE_SLAMMED
+		 * phone.
+		 */
+		if ((phone->state == IPC_PHONE_CONNECTED) ||
+		    (phone->state == IPC_PHONE_SLAMMED)) {
+			mutex_unlock(&phone->lock);
+			ipc_phone_hangup(phone);
+			/*
+			 * Now there may be one extra active call, which needs
+			 * to be forgotten.
+			 */
+			ipc_forget_all_active_calls();
+			goto restart;
+		}
+
+		/*
+		 * If the hangup succeeded, it has sent a HANGUP message, the
+		 * IPC is now in HUNGUP state, we wait for the reply to come
+		 */
+		if (phone->state != IPC_PHONE_FREE) {
+			mutex_unlock(&phone->lock);
+			break;
+		}
+
+		mutex_unlock(&phone->lock);
+	}
+		
+	/* Got into cleanup */
+	if (i == IPC_MAX_PHONES)
+		return;
+		
+	call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
+	    SYNCH_FLAGS_NONE);
+	ASSERT(call->flags & (IPC_CALL_ANSWERED | IPC_CALL_NOTIF));
+	ipc_call_free(call);
+	goto restart;
+}
+
 /** Clean up all IPC communication of the current task.
  *
@@ -537,7 +725,16 @@
 void ipc_cleanup(void)
 {
+	/*
+	 * Mark the answerbox as inactive.
+	 *
+	 * The main purpose for doing this is to prevent any pending callback
+	 * connections from getting established beyond this point.
+	 */
+	irq_spinlock_lock(&TASK->answerbox.lock, true);
+	TASK->answerbox.active = false;
+	irq_spinlock_unlock(&TASK->answerbox.lock, true);
+
 	/* Disconnect all our phones ('ipc_phone_hangup') */
-	size_t i;
-	for (i = 0; i < IPC_MAX_PHONES; i++)
+	for (size_t i = 0; i < IPC_MAX_PHONES; i++)
 		ipc_phone_hangup(&TASK->phones[i]);
 	
@@ -557,51 +754,10 @@
 	
 	/* Answer all messages in 'calls' and 'dispatched_calls' queues */
-	irq_spinlock_lock(&TASK->answerbox.lock, true);
-	ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls);
-	ipc_cleanup_call_list(&TASK->answerbox.calls);
-	irq_spinlock_unlock(&TASK->answerbox.lock, true);
-	
-	/* Wait for all answers to asynchronous calls to arrive */
-	while (true) {
-		/*
-		 * Go through all phones, until they are all FREE
-		 * Locking is not needed, no one else should modify
-		 * it when we are in cleanup
-		 */
-		for (i = 0; i < IPC_MAX_PHONES; i++) {
-			if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
-			    atomic_get(&TASK->phones[i].active_calls) == 0) {
-				TASK->phones[i].state = IPC_PHONE_FREE;
-				TASK->phones[i].callee = NULL;
-			}
-			
-			/*
-			 * Just for sure, we might have had some
-			 * IPC_PHONE_CONNECTING phones
-			 */
-			if (TASK->phones[i].state == IPC_PHONE_CONNECTED)
-				ipc_phone_hangup(&TASK->phones[i]);
-			
-			/*
-			 * If the hangup succeeded, it has sent a HANGUP
-			 * message, the IPC is now in HUNGUP state, we
-			 * wait for the reply to come
-			 */
-			
-			if (TASK->phones[i].state != IPC_PHONE_FREE)
-				break;
-		}
-		
-		/* Got into cleanup */
-		if (i == IPC_MAX_PHONES)
-			break;
-		
-		call_t *call = ipc_wait_for_call(&TASK->answerbox, SYNCH_NO_TIMEOUT,
-		    SYNCH_FLAGS_NONE);
-		ASSERT((call->flags & IPC_CALL_ANSWERED) ||
-		    (call->flags & IPC_CALL_NOTIF));
-		
-		ipc_call_free(call);
-	}
+	ipc_cleanup_call_list(&TASK->answerbox,
+	    &TASK->answerbox.dispatched_calls);
+	ipc_cleanup_call_list(&TASK->answerbox, &TASK->answerbox.calls);
+
+	ipc_forget_all_active_calls();
+	ipc_wait_for_all_answered_calls();
 }
 
@@ -615,4 +771,38 @@
 	ipc_answerbox_slab = slab_cache_create("answerbox_t",
 	    sizeof(answerbox_t), 0, NULL, NULL, 0);
+}
+
+
+static void ipc_print_call_list(list_t *list)
+{
+	list_foreach(*list, cur) {
+		call_t *call = list_get_instance(cur, call_t, ab_link);
+		
+#ifdef __32_BITS__
+		printf("%10p ", call);
+#endif
+		
+#ifdef __64_BITS__
+		printf("%18p ", call);
+#endif
+		
+		spinlock_lock(&call->forget_lock);
+
+		printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
+		    " %-6" PRIun " %-6" PRIun " %-7x",
+		    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
+		    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
+		    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
+		    call->flags);
+
+		if (call->forget) {
+			printf(" ? (call forgotten)\n");
+		} else {
+			printf(" %" PRIu64 " (%s)\n",
+			    call->sender->taskid, call->sender->name);
+		}
+
+		spinlock_unlock(&call->forget_lock);
+	}
 }
 
@@ -688,62 +878,9 @@
 	
 	printf(" --- incomming calls ---\n");
-	list_foreach(task->answerbox.calls, cur) {
-		call_t *call = list_get_instance(cur, call_t, link);
-		
-#ifdef __32_BITS__
-		printf("%10p ", call);
-#endif
-		
-#ifdef __64_BITS__
-		printf("%18p ", call);
-#endif
-		
-		printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
-		    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
-		    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
-		    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
-		    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
-		    call->flags, call->sender->taskid, call->sender->name);
-	}
-	
+	ipc_print_call_list(&task->answerbox.calls);
 	printf(" --- dispatched calls ---\n");
-	list_foreach(task->answerbox.dispatched_calls, cur) {
-		call_t *call = list_get_instance(cur, call_t, link);
-		
-#ifdef __32_BITS__
-		printf("%10p ", call);
-#endif
-		
-#ifdef __64_BITS__
-		printf("%18p ", call);
-#endif
-		
-		printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
-		    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
-		    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
-		    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
-		    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
-		    call->flags, call->sender->taskid, call->sender->name);
-	}
-	
+	ipc_print_call_list(&task->answerbox.dispatched_calls);
 	printf(" --- incoming answers ---\n");
-	list_foreach(task->answerbox.answers, cur) {
-		call_t *call = list_get_instance(cur, call_t, link);
-		
-#ifdef __32_BITS__
-		printf("%10p ", call);
-#endif
-		
-#ifdef __64_BITS__
-		printf("%18p ", call);
-#endif
-		
-		printf("%-8" PRIun " %-6" PRIun " %-6" PRIun " %-6" PRIun
-		    " %-6" PRIun " %-6" PRIun " %-7x %" PRIu64 " (%s)\n",
-		    IPC_GET_IMETHOD(call->data), IPC_GET_ARG1(call->data),
-		    IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data),
-		    IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data),
-		    call->flags, call->sender->taskid, call->sender->name);
-	}
+	ipc_print_call_list(&task->answerbox.answers);
 	
 	irq_spinlock_unlock(&task->answerbox.lock, false);
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -132,4 +132,5 @@
 #include <ipc/ipcrsc.h>
 #include <debug.h>
+#include <abi/errno.h>
 
 /** Find call_t * in call table according to callid.
@@ -151,5 +152,5 @@
 	
 	list_foreach(TASK->answerbox.dispatched_calls, lst) {
-		call_t *call = list_get_instance(lst, call_t, link);
+		call_t *call = list_get_instance(lst, call_t, ab_link);
 		if ((sysarg_t) call == callid) {
 			result = call;
@@ -162,4 +163,21 @@
 }
 
+/** Get phone from the current task by ID.
+ *
+ * @param phoneid Phone ID.
+ * @param phone   Place to store pointer to phone.
+ *
+ * @return EOK on success, EINVAL if ID is invalid.
+ *
+ */
+int phone_get(sysarg_t phoneid, phone_t **phone)
+{
+	if (phoneid >= IPC_MAX_PHONES)
+		return EINVAL;
+	
+	*phone = &TASK->phones[phoneid];
+	return EOK;
+}
+
 /** Allocate new phone slot in the specified task.
  *
@@ -176,10 +194,12 @@
 	size_t i;
 	for (i = 0; i < IPC_MAX_PHONES; i++) {
-		if ((task->phones[i].state == IPC_PHONE_HUNGUP) &&
-		    (atomic_get(&task->phones[i].active_calls) == 0))
-			task->phones[i].state = IPC_PHONE_FREE;
+		phone_t *phone = &task->phones[i];
+
+		if ((phone->state == IPC_PHONE_HUNGUP) &&
+		    (atomic_get(&phone->active_calls) == 0))
+			phone->state = IPC_PHONE_FREE;
 		
-		if (task->phones[i].state == IPC_PHONE_FREE) {
-			task->phones[i].state = IPC_PHONE_CONNECTING;
+		if (phone->state == IPC_PHONE_FREE) {
+			phone->state = IPC_PHONE_CONNECTING;
 			break;
 		}
@@ -223,4 +243,5 @@
  * @param phoneid Phone handle to be connected.
  * @param box     Answerbox to which to connect the phone handle.
+ * @return        True if the phone was connected, false otherwise.
  *
  * The procedure _enforces_ that the user first marks the phone
@@ -229,10 +250,10 @@
  *
  */
-void phone_connect(int phoneid, answerbox_t *box)
+bool phone_connect(int phoneid, answerbox_t *box)
 {
 	phone_t *phone = &TASK->phones[phoneid];
 	
 	ASSERT(phone->state == IPC_PHONE_CONNECTING);
-	ipc_phone_connect(phone, box);
+	return ipc_phone_connect(phone, box);
 }
 
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/irq.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -510,5 +510,5 @@
 {
 	irq_spinlock_lock(&irq->notif_cfg.answerbox->irq_lock, false);
-	list_append(&call->link, &irq->notif_cfg.answerbox->irq_notifs);
+	list_append(&call->ab_link, &irq->notif_cfg.answerbox->irq_notifs);
 	irq_spinlock_unlock(&irq->notif_cfg.answerbox->irq_lock, false);
 	
Index: kernel/generic/src/ipc/kbox.c
===================================================================
--- kernel/generic/src/ipc/kbox.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/kbox.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -48,4 +48,12 @@
 {
 	/*
+	 * Not really needed, just to be consistent with the meaning of
+	 * answerbox_t.active.
+	 */
+	irq_spinlock_lock(&TASK->kb.box.lock, true);
+	TASK->kb.box.active = false;
+	irq_spinlock_unlock(&TASK->kb.box.lock, true);
+
+	/*
 	 * Only hold kb.cleanup_lock while setting kb.finished -
 	 * this is enough.
@@ -88,8 +96,6 @@
 	
 	/* Answer all messages in 'calls' and 'dispatched_calls' queues. */
-	irq_spinlock_lock(&TASK->kb.box.lock, true);
-	ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
-	ipc_cleanup_call_list(&TASK->kb.box.calls);
-	irq_spinlock_unlock(&TASK->kb.box.lock, true);
+	ipc_cleanup_call_list(&TASK->kb.box, &TASK->kb.box.dispatched_calls);
+	ipc_cleanup_call_list(&TASK->kb.box, &TASK->kb.box.calls);
 }
 
@@ -162,5 +168,5 @@
 	while (!done) {
 		call_t *call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
-			SYNCH_FLAGS_NONE);
+		    SYNCH_FLAGS_NONE);
 		
 		if (call == NULL)
@@ -236,5 +242,5 @@
 	
 	/* Connect the newly allocated phone to the kbox */
-	ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
+	(void) ipc_phone_connect(&TASK->phones[newphid], &task->kb.box);
 	
 	if (task->kb.thread != NULL) {
Index: kernel/generic/src/ipc/ops/clnestab.c
===================================================================
--- kernel/generic/src/ipc/ops/clnestab.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/clnestab.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <synch/mutex.h>
+#include <abi/errno.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	IPC_SET_ARG5(call->data, (sysarg_t) phone);
+
+	return EOK;	
+}
+
+static void answer_cleanup(call_t *answer, ipc_data_t *olddata)
+{
+	phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
+
+	mutex_lock(&phone->lock);
+	if (phone->state == IPC_PHONE_CONNECTED) {
+		irq_spinlock_lock(&phone->callee->lock, true);
+		list_remove(&phone->link);
+		phone->state = IPC_PHONE_SLAMMED;
+		irq_spinlock_unlock(&phone->callee->lock, true);
+	}
+	mutex_unlock(&phone->lock);
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+
+	if (IPC_GET_RETVAL(answer->data) != EOK) {
+		/*
+		 * The other party on the cloned phone rejected our request
+		 * for connection on the protocol level.  We need to break the
+		 * connection without sending IPC_M_HUNGUP back.
+		 */
+		answer_cleanup(answer, olddata);
+	}
+	
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_clone_establish_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/conctmeto.c
===================================================================
--- kernel/generic/src/ipc/ops/conctmeto.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/conctmeto.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <ipc/ipcrsc.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	int newphid = phone_alloc(TASK);
+
+	if (newphid < 0)
+		return ELIMIT;
+		
+	/* Set arg5 for server */
+	IPC_SET_ARG5(call->data, (sysarg_t) &TASK->phones[newphid]);
+	call->priv = newphid;
+
+	return EOK;
+}
+
+static void request_forget(call_t *call)
+{
+	phone_dealloc(call->priv);
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
+
+	/* If the user accepted call, connect */
+	if (IPC_GET_RETVAL(answer->data) == EOK)
+		(void) ipc_phone_connect(phone, &TASK->answerbox);
+
+	return EOK;
+}
+
+static int answer_process(call_t *answer)
+{
+	if (IPC_GET_RETVAL(answer->data))
+		phone_dealloc(answer->priv);
+	else
+		IPC_SET_ARG5(answer->data, answer->priv);
+	
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_connect_me_to_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/concttome.c
===================================================================
--- kernel/generic/src/ipc/ops/concttome.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/concttome.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <ipc/ipcrsc.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	/* Start with the assumption that there is no allocated phoneid. */
+	IPC_SET_ARG5(call->data, -1);
+	return EOK;
+}
+
+static int request_process(call_t *call, answerbox_t *box)
+{
+	int phoneid = phone_alloc(TASK);
+
+	IPC_SET_ARG5(call->data, phoneid);
+	
+	return EOK;
+}
+
+static void answer_cleanup(call_t *answer, ipc_data_t *olddata)
+{
+	int phoneid = (int) IPC_GET_ARG5(*olddata);
+
+	if (phoneid >= 0)
+		phone_dealloc(phoneid);
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	int phoneid = (int) IPC_GET_ARG5(*olddata);
+
+	if (IPC_GET_RETVAL(answer->data) != EOK) {
+		/* The connection was not accepted */
+		answer_cleanup(answer, olddata);
+	} else if (phoneid >= 0) {
+		/* The connection was accepted */
+		if (phone_connect(phoneid, &answer->sender->answerbox)) {
+			/* Set 'phone hash' as arg5 of response */
+			IPC_SET_ARG5(answer->data,
+			    (sysarg_t) &TASK->phones[phoneid]);
+		} else {
+			/* The answerbox is shutting down. */
+			IPC_SET_RETVAL(answer->data, ENOENT);
+			answer_cleanup(answer, olddata);
+		}
+	} else {
+		IPC_SET_RETVAL(answer->data, ELIMIT);
+	}
+
+	return EOK;
+}
+
+
+sysipc_ops_t ipc_m_connect_to_me_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = request_process,
+	.answer_cleanup = answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/connclone.c
===================================================================
--- kernel/generic/src/ipc/ops/connclone.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/connclone.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <ipc/ipcrsc.h>
+#include <synch/mutex.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static void phones_lock(phone_t *p1, phone_t *p2)
+{
+	if (p1 < p2) {
+		mutex_lock(&p1->lock);
+		mutex_lock(&p2->lock);
+	} else if (p1 > p2) {
+		mutex_lock(&p2->lock);
+		mutex_lock(&p1->lock);
+	} else
+		mutex_lock(&p1->lock);
+}
+
+static void phones_unlock(phone_t *p1, phone_t *p2)
+{
+	mutex_unlock(&p1->lock);
+	if (p1 != p2)
+		mutex_unlock(&p2->lock);
+}
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	phone_t *cloned_phone;
+
+	if (phone_get(IPC_GET_ARG1(call->data), &cloned_phone) != EOK)
+		return ENOENT;
+		
+	phones_lock(cloned_phone, phone);
+		
+	if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
+	    phone->state != IPC_PHONE_CONNECTED) {
+		phones_unlock(cloned_phone, phone);
+		return EINVAL;
+	}
+		
+	/*
+	 * We can be pretty sure now that both tasks exist and we are
+	 * connected to them. As we continue to hold the phone locks,
+	 * we are effectively preventing them from finishing their
+	 * potential cleanup.
+	 *
+	 */
+	int newphid = phone_alloc(phone->callee->task);
+	if (newphid < 0) {
+		phones_unlock(cloned_phone, phone);
+		return ELIMIT;
+	}
+		
+	(void) ipc_phone_connect(&phone->callee->task->phones[newphid],
+	    cloned_phone->callee);
+	phones_unlock(cloned_phone, phone);
+		
+	/* Set the new phone for the callee. */
+	IPC_SET_ARG1(call->data, newphid);
+
+	return EOK;
+}
+
+static void answer_cleanup(call_t *answer, ipc_data_t *olddata)
+{
+	int phoneid = (int) IPC_GET_ARG1(*olddata);
+	phone_t *phone = &TASK->phones[phoneid];
+
+	/*
+	 * In this case, the connection was established at the request
+	 * time and therefore we need to slam the phone.  We don't
+	 * merely hangup as that would result in sending IPC_M_HUNGUP
+	 * to the third party on the other side of the cloned phone.
+	 */
+	mutex_lock(&phone->lock);
+	if (phone->state == IPC_PHONE_CONNECTED) {
+		irq_spinlock_lock(&phone->callee->lock, true);
+		list_remove(&phone->link);
+		phone->state = IPC_PHONE_SLAMMED;
+		irq_spinlock_unlock(&phone->callee->lock, true);
+	}
+	mutex_unlock(&phone->lock);
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	if (IPC_GET_RETVAL(answer->data) != EOK) {
+		/*
+		 * The recipient of the cloned phone rejected the offer.
+		 */
+		answer_cleanup(answer, olddata);
+	}
+
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_connection_clone_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/dataread.c
===================================================================
--- kernel/generic/src/ipc/ops/dataread.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/dataread.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <mm/slab.h>
+#include <abi/errno.h>
+#include <syscall/copy.h>
+#include <config.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	size_t size = IPC_GET_ARG2(call->data);
+
+	if (size > DATA_XFER_LIMIT) {
+		int flags = IPC_GET_ARG3(call->data);
+
+		if (flags & IPC_XF_RESTRICT)
+			IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
+		else
+			return ELIMIT;
+	}
+
+	return EOK;
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	ASSERT(!answer->buffer);
+
+	if (!IPC_GET_RETVAL(answer->data)) {
+		/* The recipient agreed to send data. */
+		uintptr_t src = IPC_GET_ARG1(answer->data);
+		uintptr_t dst = IPC_GET_ARG1(*olddata);
+		size_t max_size = IPC_GET_ARG2(*olddata);
+		size_t size = IPC_GET_ARG2(answer->data);
+
+		if (size && size <= max_size) {
+			/*
+			 * Copy the destination VA so that this piece of
+			 * information is not lost.
+			 */
+			IPC_SET_ARG1(answer->data, dst);
+				
+			answer->buffer = malloc(size, 0);
+			int rc = copy_from_uspace(answer->buffer,
+			    (void *) src, size);
+			if (rc) {
+				IPC_SET_RETVAL(answer->data, rc);
+				/*
+				 * answer->buffer will be cleaned up in
+				 * ipc_call_free().
+				 */
+			}
+		} else if (!size) {
+			IPC_SET_RETVAL(answer->data, EOK);
+		} else {
+			IPC_SET_RETVAL(answer->data, ELIMIT);
+		}
+	}
+
+	return EOK;
+}
+
+static int answer_process(call_t *answer)
+{
+	if (answer->buffer) {
+		uintptr_t dst = IPC_GET_ARG1(answer->data);
+		size_t size = IPC_GET_ARG2(answer->data);
+		int rc;
+
+		rc = copy_to_uspace((void *) dst, answer->buffer, size);
+		if (rc)
+			IPC_SET_RETVAL(answer->data, rc);
+	}
+
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_data_read_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/datawrite.c
===================================================================
--- kernel/generic/src/ipc/ops/datawrite.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/datawrite.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <mm/slab.h>
+#include <abi/errno.h>
+#include <syscall/copy.h>
+#include <config.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	uintptr_t src = IPC_GET_ARG1(call->data);
+	size_t size = IPC_GET_ARG2(call->data);
+
+	if (size > DATA_XFER_LIMIT) {
+		int flags = IPC_GET_ARG3(call->data);
+
+		if (flags & IPC_XF_RESTRICT) {
+			size = DATA_XFER_LIMIT;
+			IPC_SET_ARG2(call->data, size);
+		} else
+			return ELIMIT;
+	}
+
+	call->buffer = (uint8_t *) malloc(size, 0);
+	int rc = copy_from_uspace(call->buffer, (void *) src, size);
+	if (rc != 0) {
+		/*
+		 * call->buffer will be cleaned up in ipc_call_free() at the
+		 * latest.
+		 */
+		return rc;
+	}
+		
+	return EOK;
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	ASSERT(answer->buffer);
+
+	if (!IPC_GET_RETVAL(answer->data)) {
+		/* The recipient agreed to receive data. */
+		uintptr_t dst = (uintptr_t)IPC_GET_ARG1(answer->data);
+		size_t size = (size_t)IPC_GET_ARG2(answer->data);
+		size_t max_size = (size_t)IPC_GET_ARG2(*olddata);
+			
+		if (size <= max_size) {
+			int rc = copy_to_uspace((void *) dst,
+			    answer->buffer, size);
+			if (rc)
+				IPC_SET_RETVAL(answer->data, rc);
+		} else {
+			IPC_SET_RETVAL(answer->data, ELIMIT);
+		}
+	}
+
+	return EOK;
+}
+
+
+sysipc_ops_t ipc_m_data_write_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/debug.c
===================================================================
--- kernel/generic/src/ipc/ops/debug.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/debug.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2008 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <udebug/udebug_ipc.h>
+#include <syscall/copy.h>
+#include <abi/errno.h>
+
+static int request_process(call_t *call, answerbox_t *box)
+{
+	return -1;
+}
+
+static int answer_process(call_t *answer)
+{
+	if (answer->buffer) {
+		uintptr_t dst = IPC_GET_ARG1(answer->data);
+		size_t size = IPC_GET_ARG2(answer->data);
+		int rc;
+
+		rc = copy_to_uspace((void *) dst, answer->buffer, size);
+		if (rc)
+			IPC_SET_RETVAL(answer->data, rc);
+	}
+
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_debug_ops = {
+#ifdef CONFIG_UDEBUG
+	.request_preprocess = udebug_request_preprocess,
+#else
+	.request_preprocess = null_request_preprocess,
+#endif
+	.request_forget = null_request_forget,
+	.request_process = request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = null_answer_preprocess,
+	.answer_process = answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/sharein.c
===================================================================
--- kernel/generic/src/ipc/ops/sharein.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/sharein.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <mm/as.h>
+#include <synch/spinlock.h>
+#include <proc/task.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	if (!IPC_GET_RETVAL(answer->data)) {
+		irq_spinlock_lock(&answer->sender->lock, true);
+		as_t *as = answer->sender->as;
+		irq_spinlock_unlock(&answer->sender->lock, true);
+			
+		uintptr_t dst_base = (uintptr_t) -1;
+		int rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
+		    IPC_GET_ARG1(*olddata), as, IPC_GET_ARG2(answer->data),
+		    &dst_base, IPC_GET_ARG3(answer->data));
+		IPC_SET_ARG4(answer->data, dst_base);
+		IPC_SET_RETVAL(answer->data, rc);
+	}
+	
+	return EOK;
+}
+
+sysipc_ops_t ipc_m_share_in_ops = {
+	.request_preprocess = null_request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/shareout.c
===================================================================
--- kernel/generic/src/ipc/ops/shareout.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/shareout.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <mm/as.h>
+#include <synch/spinlock.h>
+#include <proc/task.h>
+#include <syscall/copy.h>
+#include <abi/errno.h>
+#include <arch.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	size_t size = as_area_get_size(IPC_GET_ARG1(call->data));
+
+	if (!size)
+		return EPERM;
+	IPC_SET_ARG2(call->data, size);
+
+	return EOK;
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	int rc = EOK;
+
+	if (!IPC_GET_RETVAL(answer->data)) {
+		/* Accepted, handle as_area receipt */
+
+		irq_spinlock_lock(&answer->sender->lock, true);
+		as_t *as = answer->sender->as;
+		irq_spinlock_unlock(&answer->sender->lock, true);
+
+		uintptr_t dst_base = (uintptr_t) -1;
+		rc = as_area_share(as, IPC_GET_ARG1(*olddata),
+		    IPC_GET_ARG2(*olddata), AS, IPC_GET_ARG3(*olddata),
+		    &dst_base, IPC_GET_ARG1(answer->data));
+			
+		if (rc == EOK) {
+			rc = copy_to_uspace((void *) IPC_GET_ARG2(answer->data),
+			    &dst_base, sizeof(dst_base));
+		}
+			
+		IPC_SET_RETVAL(answer->data, rc);
+	}
+
+	return rc;
+}
+
+sysipc_ops_t ipc_m_share_out_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/ops/stchngath.c
===================================================================
--- kernel/generic/src/ipc/ops/stchngath.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/ops/stchngath.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <ipc/ipc.h>
+#include <ipc/ipcrsc.h>
+#include <synch/mutex.h>
+#include <proc/task.h>
+#include <abi/errno.h>
+#include <macros.h>
+
+static int request_preprocess(call_t *call, phone_t *phone)
+{
+	phone_t *sender_phone;
+	task_t *other_task_s;
+
+	if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
+		return ENOENT;
+
+	mutex_lock(&sender_phone->lock);
+	if (sender_phone->state != IPC_PHONE_CONNECTED) {
+		mutex_unlock(&sender_phone->lock);
+		return EINVAL;
+	}
+
+	other_task_s = sender_phone->callee->task;
+
+	mutex_unlock(&sender_phone->lock);
+
+	/* Remember the third party task hash. */
+	IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
+
+	return EOK;
+}
+
+static int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	int rc = EOK;
+
+	if (!IPC_GET_RETVAL(answer->data)) {
+		/* The recipient authorized the change of state. */
+		phone_t *recipient_phone;
+		task_t *other_task_s;
+		task_t *other_task_r;
+
+		rc = phone_get(IPC_GET_ARG1(answer->data),
+		    &recipient_phone);
+		if (rc != EOK) {
+			IPC_SET_RETVAL(answer->data, ENOENT);
+			return ENOENT;
+		}
+
+		mutex_lock(&recipient_phone->lock);
+		if (recipient_phone->state != IPC_PHONE_CONNECTED) {
+			mutex_unlock(&recipient_phone->lock);
+			IPC_SET_RETVAL(answer->data, EINVAL);
+			return EINVAL;
+		}
+
+		other_task_r = recipient_phone->callee->task;
+		other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
+
+		/*
+		 * See if both the sender and the recipient meant the
+		 * same third party task.
+		 */
+		if (other_task_r != other_task_s) {
+			IPC_SET_RETVAL(answer->data, EINVAL);
+			rc = EINVAL;
+		} else {
+			rc = event_task_notify_5(other_task_r,
+			    EVENT_TASK_STATE_CHANGE, false,
+			    IPC_GET_ARG1(*olddata),
+			    IPC_GET_ARG2(*olddata),
+			    IPC_GET_ARG3(*olddata),
+			    LOWER32(olddata->task_id),
+			    UPPER32(olddata->task_id));
+			IPC_SET_RETVAL(answer->data, rc);
+		}
+
+		mutex_unlock(&recipient_phone->lock);
+	}
+
+	return rc;
+}
+
+sysipc_ops_t ipc_m_state_change_authorize_ops = {
+	.request_preprocess = request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+/** @}
+ */
Index: kernel/generic/src/ipc/sysipc.c
===================================================================
--- kernel/generic/src/ipc/sysipc.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/ipc/sysipc.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -34,12 +34,11 @@
 
 #include <arch.h>
-#include <proc/task.h>
-#include <proc/thread.h>
 #include <errno.h>
 #include <memstr.h>
-#include <debug.h>
 #include <ipc/ipc.h>
 #include <abi/ipc/methods.h>
 #include <ipc/sysipc.h>
+#include <ipc/sysipc_ops.h>
+#include <ipc/sysipc_priv.h>
 #include <ipc/irq.h>
 #include <ipc/ipcrsc.h>
@@ -47,37 +46,12 @@
 #include <ipc/kbox.h>
 #include <synch/waitq.h>
-#include <udebug/udebug_ipc.h>
 #include <arch/interrupt.h>
 #include <syscall/copy.h>
 #include <security/cap.h>
 #include <console/console.h>
-#include <mm/as.h>
 #include <print.h>
 #include <macros.h>
 
-/**
- * Maximum buffer size allowed for IPC_M_DATA_WRITE and IPC_M_DATA_READ
- * requests.
- */
-#define DATA_XFER_LIMIT  (64 * 1024)
-
 #define STRUCT_TO_USPACE(dst, src)  copy_to_uspace((dst), (src), sizeof(*(src)))
-
-/** Get phone from the current task by ID.
- *
- * @param phoneid Phone ID.
- * @param phone   Place to store pointer to phone.
- *
- * @return EOK on success, EINVAL if ID is invalid.
- *
- */
-static int phone_get(sysarg_t phoneid, phone_t **phone)
-{
-	if (phoneid >= IPC_MAX_PHONES)
-		return EINVAL;
-	
-	*phone = &TASK->phones[phoneid];
-	return EOK;
-}
 
 /** Decide if the interface and method is a system method.
@@ -181,235 +155,67 @@
  * @param olddata Saved data of the request.
  *
- * @return Return 0 on success or an error code.
- *
- */
-static inline int answer_preprocess(call_t *answer, ipc_data_t *olddata)
-{
+ * @return Return EOK on success or a negative error code.
+ *
+ */
+int answer_preprocess(call_t *answer, ipc_data_t *olddata)
+{
+	int rc = EOK;
+	sysipc_ops_t *ops;
+
+	spinlock_lock(&answer->forget_lock);
+	if (answer->forget) {
+		/*
+		 * This is a forgotten call and answer->sender is not valid.
+		 */
+		spinlock_unlock(&answer->forget_lock);
+
+		ops = sysipc_ops_get(answer->request_method);
+		if (ops->answer_cleanup)
+			ops->answer_cleanup(answer, olddata);
+
+		return rc;
+	} else {
+		ASSERT(answer->active);
+
+		/*
+		 * Mark the call as inactive to prevent _ipc_answer_free_call()
+		 * from attempting to remove the call from the active list
+		 * itself.
+		 */
+		answer->active = false;
+
+		/*
+		 * Remove the call from the sender's active call list.
+		 * We enforce this locking order so that any potential
+		 * concurrently executing forget operation is forced to
+		 * release its active_calls_lock and lose the race to
+		 * forget this soon to be answered call. 
+		 */
+		spinlock_lock(&answer->sender->active_calls_lock);
+		list_remove(&answer->ta_link);
+		spinlock_unlock(&answer->sender->active_calls_lock);
+	}
+	spinlock_unlock(&answer->forget_lock);
+
 	if ((native_t) IPC_GET_RETVAL(answer->data) == EHANGUP) {
-		/* In case of forward, hangup the forwared phone,
-		 * not the originator
-		 */
-		mutex_lock(&answer->data.phone->lock);
-		irq_spinlock_lock(&TASK->answerbox.lock, true);
-		if (answer->data.phone->state == IPC_PHONE_CONNECTED) {
-			list_remove(&answer->data.phone->link);
-			answer->data.phone->state = IPC_PHONE_SLAMMED;
+		phone_t *phone = answer->caller_phone;
+		mutex_lock(&phone->lock);
+		if (phone->state == IPC_PHONE_CONNECTED) {
+			irq_spinlock_lock(&phone->callee->lock, true);
+			list_remove(&phone->link);
+			phone->state = IPC_PHONE_SLAMMED;
+			irq_spinlock_unlock(&phone->callee->lock, true);
 		}
-		irq_spinlock_unlock(&TASK->answerbox.lock, true);
-		mutex_unlock(&answer->data.phone->lock);
+		mutex_unlock(&phone->lock);
 	}
 	
 	if (!olddata)
-		return 0;
-	
-	if (IPC_GET_IMETHOD(*olddata) == IPC_M_CONNECTION_CLONE) {
-		int phoneid = IPC_GET_ARG1(*olddata);
-		phone_t *phone = &TASK->phones[phoneid];
-		
-		if (IPC_GET_RETVAL(answer->data) != EOK) {
-			/*
-			 * The recipient of the cloned phone rejected the offer.
-			 * In this case, the connection was established at the
-			 * request time and therefore we need to slam the phone.
-			 * We don't merely hangup as that would result in
-			 * sending IPC_M_HUNGUP to the third party on the
-			 * other side of the cloned phone.
-			 */
-			mutex_lock(&phone->lock);
-			if (phone->state == IPC_PHONE_CONNECTED) {
-				irq_spinlock_lock(&phone->callee->lock, true);
-				list_remove(&phone->link);
-				phone->state = IPC_PHONE_SLAMMED;
-				irq_spinlock_unlock(&phone->callee->lock, true);
-			}
-			mutex_unlock(&phone->lock);
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_CLONE_ESTABLISH) {
-		phone_t *phone = (phone_t *) IPC_GET_ARG5(*olddata);
-		
-		if (IPC_GET_RETVAL(answer->data) != EOK) {
-			/*
-			 * The other party on the cloned phoned rejected our
-			 * request for connection on the protocol level.
-			 * We need to break the connection without sending
-			 * IPC_M_HUNGUP back.
-			 */
-			mutex_lock(&phone->lock);
-			if (phone->state == IPC_PHONE_CONNECTED) {
-				irq_spinlock_lock(&phone->callee->lock, true);
-				list_remove(&phone->link);
-				phone->state = IPC_PHONE_SLAMMED;
-				irq_spinlock_unlock(&phone->callee->lock, true);
-			}
-			mutex_unlock(&phone->lock);
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
-		int phoneid = IPC_GET_ARG5(*olddata);
-		
-		if (IPC_GET_RETVAL(answer->data) != EOK) {
-			/* The connection was not accepted */
-			phone_dealloc(phoneid);
-		} else {
-			/* The connection was accepted */
-			phone_connect(phoneid, &answer->sender->answerbox);
-			/* Set 'phone hash' as arg5 of response */
-			IPC_SET_ARG5(answer->data,
-			    (sysarg_t) &TASK->phones[phoneid]);
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
-		/* If the users accepted call, connect */
-		if (IPC_GET_RETVAL(answer->data) == EOK) {
-			ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
-			    &TASK->answerbox);
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_SHARE_OUT) {
-		if (!IPC_GET_RETVAL(answer->data)) {
-			/* Accepted, handle as_area receipt */
-			
-			irq_spinlock_lock(&answer->sender->lock, true);
-			as_t *as = answer->sender->as;
-			irq_spinlock_unlock(&answer->sender->lock, true);
-			
-			uintptr_t dst_base = (uintptr_t) -1;
-			int rc = as_area_share(as, IPC_GET_ARG1(*olddata),
-			    IPC_GET_ARG2(*olddata), AS, IPC_GET_ARG3(*olddata),
-			    &dst_base, IPC_GET_ARG1(answer->data));
-			
-			if (rc == EOK)
-				rc = copy_to_uspace((void *) IPC_GET_ARG2(answer->data),
-				    &dst_base, sizeof(dst_base));
-			
-			IPC_SET_RETVAL(answer->data, rc);
-			return rc;
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_SHARE_IN) {
-		if (!IPC_GET_RETVAL(answer->data)) {
-			irq_spinlock_lock(&answer->sender->lock, true);
-			as_t *as = answer->sender->as;
-			irq_spinlock_unlock(&answer->sender->lock, true);
-			
-			uintptr_t dst_base = (uintptr_t) -1;
-			int rc = as_area_share(AS, IPC_GET_ARG1(answer->data),
-			    IPC_GET_ARG1(*olddata), as, IPC_GET_ARG2(answer->data),
-			    &dst_base, IPC_GET_ARG3(answer->data));
-			IPC_SET_ARG4(answer->data, dst_base);
-			IPC_SET_RETVAL(answer->data, rc);
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_DATA_READ) {
-		ASSERT(!answer->buffer);
-		if (!IPC_GET_RETVAL(answer->data)) {
-			/* The recipient agreed to send data. */
-			uintptr_t src = IPC_GET_ARG1(answer->data);
-			uintptr_t dst = IPC_GET_ARG1(*olddata);
-			size_t max_size = IPC_GET_ARG2(*olddata);
-			size_t size = IPC_GET_ARG2(answer->data);
-			if (size && size <= max_size) {
-				/*
-				 * Copy the destination VA so that this piece of
-				 * information is not lost.
-				 */
-				IPC_SET_ARG1(answer->data, dst);
-				
-				answer->buffer = malloc(size, 0);
-				int rc = copy_from_uspace(answer->buffer,
-				    (void *) src, size);
-				if (rc) {
-					IPC_SET_RETVAL(answer->data, rc);
-					free(answer->buffer);
-					answer->buffer = NULL;
-				}
-			} else if (!size) {
-				IPC_SET_RETVAL(answer->data, EOK);
-			} else {
-				IPC_SET_RETVAL(answer->data, ELIMIT);
-			}
-		}
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_DATA_WRITE) {
-		ASSERT(answer->buffer);
-		if (!IPC_GET_RETVAL(answer->data)) {
-			/* The recipient agreed to receive data. */
-			uintptr_t dst = (uintptr_t)IPC_GET_ARG1(answer->data);
-			size_t size = (size_t)IPC_GET_ARG2(answer->data);
-			size_t max_size = (size_t)IPC_GET_ARG2(*olddata);
-			
-			if (size <= max_size) {
-				int rc = copy_to_uspace((void *) dst,
-				    answer->buffer, size);
-				if (rc)
-					IPC_SET_RETVAL(answer->data, rc);
-			} else {
-				IPC_SET_RETVAL(answer->data, ELIMIT);
-			}
-		}
-		free(answer->buffer);
-		answer->buffer = NULL;
-	} else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) {
-		if (!IPC_GET_RETVAL(answer->data)) {
-			/* The recipient authorized the change of state. */
-			phone_t *recipient_phone;
-			task_t *other_task_s;
-			task_t *other_task_r;
-			int rc;
-
-			rc = phone_get(IPC_GET_ARG1(answer->data),
-			    &recipient_phone);
-			if (rc != EOK) {
-				IPC_SET_RETVAL(answer->data, ENOENT);
-				return ENOENT;
-			}
-
-			mutex_lock(&recipient_phone->lock);
-			if (recipient_phone->state != IPC_PHONE_CONNECTED) {
-				mutex_unlock(&recipient_phone->lock);
-				IPC_SET_RETVAL(answer->data, EINVAL);
-				return EINVAL;
-			}
-
-			other_task_r = recipient_phone->callee->task;
-			other_task_s = (task_t *) IPC_GET_ARG5(*olddata);
-
-			/*
-			 * See if both the sender and the recipient meant the
-			 * same third party task.
-			 */
-			if (other_task_r != other_task_s) {
-				IPC_SET_RETVAL(answer->data, EINVAL);
-				rc = EINVAL;
-			} else {
-				rc = event_task_notify_5(other_task_r,
-				    EVENT_TASK_STATE_CHANGE, false,
-				    IPC_GET_ARG1(*olddata),
-				    IPC_GET_ARG2(*olddata),
-				    IPC_GET_ARG3(*olddata),
-				    LOWER32(olddata->task_id),
-				    UPPER32(olddata->task_id));
-				IPC_SET_RETVAL(answer->data, rc);
-			}
-
-			mutex_unlock(&recipient_phone->lock);
-			return rc;
-		}
-	}
-	
-	return 0;
-}
-
-static void phones_lock(phone_t *p1, phone_t *p2)
-{
-	if (p1 < p2) {
-		mutex_lock(&p1->lock);
-		mutex_lock(&p2->lock);
-	} else if (p1 > p2) {
-		mutex_lock(&p2->lock);
-		mutex_lock(&p1->lock);
-	} else
-		mutex_lock(&p1->lock);
-}
-
-static void phones_unlock(phone_t *p1, phone_t *p2)
-{
-	mutex_unlock(&p1->lock);
-	if (p1 != p2)
-		mutex_unlock(&p2->lock);
+		return rc;
+
+	ops = sysipc_ops_get(answer->request_method);
+	if (ops->answer_preprocess)
+		rc = ops->answer_preprocess(answer, olddata);
+	
+	return rc;
 }
 
@@ -424,124 +230,13 @@
 static int request_preprocess(call_t *call, phone_t *phone)
 {
-	switch (IPC_GET_IMETHOD(call->data)) {
-	case IPC_M_CONNECTION_CLONE: {
-		phone_t *cloned_phone;
-		if (phone_get(IPC_GET_ARG1(call->data), &cloned_phone) != EOK)
-			return ENOENT;
-		
-		phones_lock(cloned_phone, phone);
-		
-		if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
-		    phone->state != IPC_PHONE_CONNECTED) {
-			phones_unlock(cloned_phone, phone);
-			return EINVAL;
-		}
-		
-		/*
-		 * We can be pretty sure now that both tasks exist and we are
-		 * connected to them. As we continue to hold the phone locks,
-		 * we are effectively preventing them from finishing their
-		 * potential cleanup.
-		 *
-		 */
-		int newphid = phone_alloc(phone->callee->task);
-		if (newphid < 0) {
-			phones_unlock(cloned_phone, phone);
-			return ELIMIT;
-		}
-		
-		ipc_phone_connect(&phone->callee->task->phones[newphid],
-		    cloned_phone->callee);
-		phones_unlock(cloned_phone, phone);
-		
-		/* Set the new phone for the callee. */
-		IPC_SET_ARG1(call->data, newphid);
-		break;
-	}
-	case IPC_M_CLONE_ESTABLISH:
-		IPC_SET_ARG5(call->data, (sysarg_t) phone);
-		break;
-	case IPC_M_CONNECT_ME_TO: {
-		int newphid = phone_alloc(TASK);
-		if (newphid < 0)
-			return ELIMIT;
-		
-		/* Set arg5 for server */
-		IPC_SET_ARG5(call->data, (sysarg_t) &TASK->phones[newphid]);
-		call->flags |= IPC_CALL_CONN_ME_TO;
-		call->priv = newphid;
-		break;
-	}
-	case IPC_M_SHARE_OUT: {
-		size_t size = as_area_get_size(IPC_GET_ARG1(call->data));
-		if (!size)
-			return EPERM;
-		
-		IPC_SET_ARG2(call->data, size);
-		break;
-	}
-	case IPC_M_DATA_READ: {
-		size_t size = IPC_GET_ARG2(call->data);
-		if (size > DATA_XFER_LIMIT) {
-			int flags = IPC_GET_ARG3(call->data);
-			if (flags & IPC_XF_RESTRICT)
-				IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
-			else
-				return ELIMIT;
-		}
-		break;
-	}
-	case IPC_M_DATA_WRITE: {
-		uintptr_t src = IPC_GET_ARG1(call->data);
-		size_t size = IPC_GET_ARG2(call->data);
-		
-		if (size > DATA_XFER_LIMIT) {
-			int flags = IPC_GET_ARG3(call->data);
-			if (flags & IPC_XF_RESTRICT) {
-				size = DATA_XFER_LIMIT;
-				IPC_SET_ARG2(call->data, size);
-			} else
-				return ELIMIT;
-		}
-		
-		call->buffer = (uint8_t *) malloc(size, 0);
-		int rc = copy_from_uspace(call->buffer, (void *) src, size);
-		if (rc != 0) {
-			free(call->buffer);
-			return rc;
-		}
-		
-		break;
-	}
-	case IPC_M_STATE_CHANGE_AUTHORIZE: {
-		phone_t *sender_phone;
-		task_t *other_task_s;
-
-		if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK)
-			return ENOENT;
-
-		mutex_lock(&sender_phone->lock);
-		if (sender_phone->state != IPC_PHONE_CONNECTED) {
-			mutex_unlock(&sender_phone->lock);
-			return EINVAL;
-		}
-
-		other_task_s = sender_phone->callee->task;
-
-		mutex_unlock(&sender_phone->lock);
-
-		/* Remember the third party task hash. */
-		IPC_SET_ARG5(call->data, (sysarg_t) other_task_s);
-		break;
-	}
-#ifdef CONFIG_UDEBUG
-	case IPC_M_DEBUG:
-		return udebug_request_preprocess(call, phone);
-#endif
-	default:
-		break;
-	}
-	
-	return 0;
+	int rc = EOK;
+
+	call->request_method = IPC_GET_IMETHOD(call->data);
+
+	sysipc_ops_t *ops = sysipc_ops_get(call->request_method);
+	if (ops->request_preprocess)
+		rc = ops->request_preprocess(call, phone);
+	
+	return rc;
 }
 
@@ -561,26 +256,9 @@
 		IPC_SET_RETVAL(call->data, EFORWARD);
 	
-	if (call->flags & IPC_CALL_CONN_ME_TO) {
-		if (IPC_GET_RETVAL(call->data))
-			phone_dealloc(call->priv);
-		else
-			IPC_SET_ARG5(call->data, call->priv);
-	}
-	
-	if (call->buffer) {
-		/*
-		 * This must be an affirmative answer to IPC_M_DATA_READ
-		 * or IPC_M_DEBUG/UDEBUG_M_MEM_READ...
-		 *
-		 */
-		uintptr_t dst = IPC_GET_ARG1(call->data);
-		size_t size = IPC_GET_ARG2(call->data);
-		int rc = copy_to_uspace((void *) dst, call->buffer, size);
-		if (rc)
-			IPC_SET_RETVAL(call->data, rc);
-		free(call->buffer);
-		call->buffer = NULL;
-	}
-}
+	sysipc_ops_t *ops = sysipc_ops_get(call->request_method);
+	if (ops->answer_process)
+		(void) ops->answer_process(call);
+}
+
 
 /** Do basic kernel processing of received call request.
@@ -595,23 +273,11 @@
 static int process_request(answerbox_t *box, call_t *call)
 {
-	if (IPC_GET_IMETHOD(call->data) == IPC_M_CONNECT_TO_ME) {
-		int phoneid = phone_alloc(TASK);
-		if (phoneid < 0) {  /* Failed to allocate phone */
-			IPC_SET_RETVAL(call->data, ELIMIT);
-			ipc_answer(box, call);
-			return -1;
-		}
-		
-		IPC_SET_ARG5(call->data, phoneid);
-	}
-	
-	switch (IPC_GET_IMETHOD(call->data)) {
-	case IPC_M_DEBUG:
-		return -1;
-	default:
-		break;
-	}
-	
-	return 0;
+	int rc = EOK;
+
+	sysipc_ops_t *ops = sysipc_ops_get(call->request_method);
+	if (ops->request_process)
+		rc = ops->request_process(call, box);
+	
+	return rc;
 }
 
@@ -745,21 +411,27 @@
 {
 	call_t *call = get_call(callid);
+	phone_t *phone;
+	bool need_old = answer_need_old(call);
+	bool after_forward = false;
+	ipc_data_t old;
+	int rc;
+
 	if (!call)
 		return ENOENT;
-	
+
+	if (need_old)
+		old = call->data;
+	
+	if (phone_get(phoneid, &phone) != EOK) {
+		rc = ENOENT;
+		goto error;
+	}
+	
+	if (!method_is_forwardable(IPC_GET_IMETHOD(call->data))) {
+		rc = EPERM;
+		goto error;
+	}
+
 	call->flags |= IPC_CALL_FORWARDED;
-	
-	phone_t *phone;
-	if (phone_get(phoneid, &phone) != EOK) {
-		IPC_SET_RETVAL(call->data, EFORWARD);
-		ipc_answer(&TASK->answerbox, call);
-		return ENOENT;
-	}
-	
-	if (!method_is_forwardable(IPC_GET_IMETHOD(call->data))) {
-		IPC_SET_RETVAL(call->data, EFORWARD);
-		ipc_answer(&TASK->answerbox, call);
-		return EPERM;
-	}
 	
 	/*
@@ -797,5 +469,21 @@
 	}
 	
-	return ipc_forward(call, phone, &TASK->answerbox, mode);
+	rc = ipc_forward(call, phone, &TASK->answerbox, mode);
+	if (rc != EOK) {
+		after_forward = true;
+		goto error;
+	}
+
+	return EOK;
+
+error:
+	IPC_SET_RETVAL(call->data, EFORWARD);
+	(void) answer_preprocess(call, need_old ? &old : NULL);
+	if (after_forward)
+		_ipc_answer_free_call(call, false);
+	else
+		ipc_answer(&TASK->answerbox, call);
+
+	return rc;
 }
 
Index: kernel/generic/src/ipc/sysipc_ops.c
===================================================================
--- kernel/generic/src/ipc/sysipc_ops.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ kernel/generic/src/ipc/sysipc_ops.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/** @addtogroup genericipc
+ * @{
+ */
+/** @file
+ */
+
+#include <ipc/sysipc_ops.h>
+#include <abi/ipc/methods.h>
+#include <abi/errno.h>
+
+/* Forward declarations. */
+sysipc_ops_t ipc_m_connection_clone_ops;
+sysipc_ops_t ipc_m_clone_establish_ops;
+sysipc_ops_t ipc_m_connect_to_me_ops;
+sysipc_ops_t ipc_m_connect_me_to_ops;
+sysipc_ops_t ipc_m_share_out_ops;
+sysipc_ops_t ipc_m_share_in_ops;
+sysipc_ops_t ipc_m_data_write_ops;
+sysipc_ops_t ipc_m_data_read_ops;
+sysipc_ops_t ipc_m_state_change_authorize_ops;
+sysipc_ops_t ipc_m_debug_ops;
+
+static sysipc_ops_t *sysipc_ops[] = {
+	[IPC_M_CONNECTION_CLONE] = &ipc_m_connection_clone_ops,
+	[IPC_M_CLONE_ESTABLISH] = &ipc_m_clone_establish_ops,
+	[IPC_M_CONNECT_TO_ME] = &ipc_m_connect_to_me_ops,
+	[IPC_M_CONNECT_ME_TO] = &ipc_m_connect_me_to_ops,
+	[IPC_M_SHARE_OUT] = &ipc_m_share_out_ops,
+	[IPC_M_SHARE_IN] = &ipc_m_share_in_ops,
+	[IPC_M_DATA_WRITE] = &ipc_m_data_write_ops,
+	[IPC_M_DATA_READ] = &ipc_m_data_read_ops,
+	[IPC_M_STATE_CHANGE_AUTHORIZE] = &ipc_m_state_change_authorize_ops,
+	[IPC_M_DEBUG] = &ipc_m_debug_ops
+};
+
+static sysipc_ops_t null_ops = {
+	.request_preprocess = null_request_preprocess,
+	.request_forget = null_request_forget,
+	.request_process = null_request_process,
+	.answer_cleanup = null_answer_cleanup,
+	.answer_preprocess = null_answer_preprocess,
+	.answer_process = null_answer_process,
+};
+
+int null_request_preprocess(call_t *call, phone_t *phone)
+{
+	return EOK;
+}
+
+void null_request_forget(call_t *call)
+{
+}
+
+int null_request_process(call_t *call, answerbox_t *box)
+{
+	return EOK;
+}
+
+void null_answer_cleanup(call_t *call, ipc_data_t *data)
+{
+}
+
+int null_answer_preprocess(call_t *call, ipc_data_t *data)
+{
+	return EOK;
+}
+
+int null_answer_process(call_t *call)
+{
+	return EOK;
+}
+
+sysipc_ops_t *sysipc_ops_get(sysarg_t imethod)
+{
+	if (imethod < sizeof(sysipc_ops) / (sizeof(sysipc_ops_t *)))
+		return sysipc_ops[imethod] ? sysipc_ops[imethod] : &null_ops;
+
+	return &null_ops;
+}
+
+/** @}
+ */
Index: kernel/generic/src/main/kinit.c
===================================================================
--- kernel/generic/src/main/kinit.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/main/kinit.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -69,4 +69,5 @@
 #include <str.h>
 #include <sysinfo/stats.h>
+#include <sysinfo/sysinfo.h>
 #include <align.h>
 
@@ -179,4 +180,26 @@
 	program_t programs[CONFIG_INIT_TASKS];
 	
+	// FIXME: do not propagate arguments through sysinfo
+	// but pass them directly to the tasks
+	for (i = 0; i < init.cnt; i++) {
+		const char *arguments = init.tasks[i].arguments;
+		if (str_length(arguments) == 0)
+			continue;
+		if (str_length(init.tasks[i].name) == 0)
+			continue;
+		size_t arguments_size = str_size(arguments);
+
+		void *arguments_copy = malloc(arguments_size, 0);
+		if (arguments_copy == NULL)
+			continue;
+		memcpy(arguments_copy, arguments, arguments_size);
+
+		char item_name[CONFIG_TASK_NAME_BUFLEN + 15];
+		snprintf(item_name, CONFIG_TASK_NAME_BUFLEN + 15,
+		    "init_args.%s", init.tasks[i].name);
+
+		sysinfo_set_item_data(item_name, NULL, arguments_copy, arguments_size);
+	}
+
 	for (i = 0; i < init.cnt; i++) {
 		if (init.tasks[i].paddr % FRAME_SIZE) {
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ kernel/generic/src/proc/task.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -161,5 +161,8 @@
 	size_t i;
 	for (i = 0; i < IPC_MAX_PHONES; i++)
-		ipc_phone_init(&task->phones[i]);
+		ipc_phone_init(&task->phones[i], task);
+
+	spinlock_initialize(&task->active_calls_lock, "active_calls_lock");
+	list_initialize(&task->active_calls);
 	
 #ifdef CONFIG_UDEBUG
@@ -203,4 +206,6 @@
 	event_task_init(task);
 	
+	task->answerbox.active = true;
+
 #ifdef CONFIG_UDEBUG
 	/* Init debugging stuff */
@@ -208,4 +213,5 @@
 	
 	/* Init kbox stuff */
+	task->kb.box.active = true;
 	task->kb.finished = false;
 #endif
@@ -213,5 +219,5 @@
 	if ((ipc_phone_0) &&
 	    (container_check(ipc_phone_0->task->container, task->container)))
-		ipc_phone_connect(&task->phones[0], ipc_phone_0);
+		(void) ipc_phone_connect(&task->phones[0], ipc_phone_0);
 	
 	btree_create(&task->futexes);
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -47,4 +47,5 @@
 	app/klog \
 	app/loc \
+	app/logset \
 	app/mkfat \
 	app/mkexfat \
@@ -78,4 +79,5 @@
 	srv/clipboard \
 	srv/locsrv \
+	srv/logger \
 	srv/devman \
 	srv/loader \
Index: uspace/app/logset/Makefile
===================================================================
--- uspace/app/logset/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/logset/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2012 Vojtech Horky
+# 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 = ../..
+BINARY = logset
+
+SOURCES = \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/logset/main.c
===================================================================
--- uspace/app/logset/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/logset/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logset
+ * @{
+ */
+/** @file Change logger behavior.
+ */
+#include <stdio.h>
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include <io/logctl.h>
+
+static log_level_t parse_log_level_or_die(const char *log_level)
+{
+	log_level_t result;
+	int rc = log_level_from_str(log_level, &result);
+	if (rc != EOK) {
+		fprintf(stderr, "Unrecognised log level '%s': %s.\n",
+		    log_level, str_error(rc));
+		exit(2);
+	}
+	return result;
+}
+
+static void usage(const char *progname)
+{
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "  %s <default-logging-level>\n", progname);
+	fprintf(stderr, "  %s <log-name> <logging-level>\n", progname);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc == 2) {
+		log_level_t new_default_level = parse_log_level_or_die(argv[1]);
+		int rc = logctl_set_default_level(new_default_level);
+
+		if (rc != EOK) {
+			fprintf(stderr, "Failed to change default logging level: %s.\n",
+			    str_error(rc));
+			return 2;
+		}
+	} else if (argc == 3) {
+		log_level_t new_level = parse_log_level_or_die(argv[2]);
+		const char *logname = argv[1];
+		int rc = logctl_set_log_level(logname, new_level);
+
+		if (rc != EOK) {
+			fprintf(stderr, "Failed to change logging level: %s.\n",
+			    str_error(rc));
+			return 2;
+		}
+	} else {
+		usage(argv[0]);
+		return 1;
+	}
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/app/tester/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -29,6 +29,6 @@
 
 USPACE_PREFIX = ../..
-LIBS = $(LIBEXT2_PREFIX)/libext2.a $(LIBBLOCK_PREFIX)/libblock.a
-EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBEXT2_PREFIX)
+LIBS = $(LIBEXT2_PREFIX)/libext2.a $(LIBBLOCK_PREFIX)/libblock.a $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
+EXTRA_CFLAGS = -I$(LIBBLOCK_PREFIX) -I$(LIBEXT2_PREFIX) -I$(LIBSOFTFLOAT_PREFIX)
 BINARY = tester
 
@@ -45,7 +45,11 @@
 	stdio/stdio1.c \
 	stdio/stdio2.c \
+	stdio/logger1.c \
+	stdio/logger2.c \
 	fault/fault1.c \
 	fault/fault2.c \
 	fault/fault3.c \
+	float/float1.c \
+	float/softfloat1.c \
 	vfs/vfs1.c \
 	ipc/ping_pong.c \
@@ -59,5 +63,5 @@
 	hw/misc/virtchar1.c \
 	hw/serial/serial1.c \
-	libext2/libext2_1.c
+	ext2/ext2_1.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/tester/ext2/ext2_1.c
===================================================================
--- uspace/app/tester/ext2/ext2_1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/ext2/ext2_1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+#include "../util.h"
+#include <libext2.h>
+#include <malloc.h>
+
+static ext2_superblock_t *fake_superblock1()
+{
+	uint8_t *buf;
+	int i;
+	
+	buf = malloc(EXT2_SUPERBLOCK_SIZE);
+	if (buf == NULL) {
+		return NULL;
+	}
+	
+	for (i = 0; i < EXT2_SUPERBLOCK_SIZE; i++) {
+		buf[i] = i % 256;
+	}
+	
+	return (ext2_superblock_t *) buf;
+}
+
+const char *test_ext2_1(void)
+{
+	ext2_superblock_t *fake1;
+	
+	TPRINTF("Testing ext2 superblock getters...\n");
+	TPRINTF("Simple test for correct position and byte order\n");
+	
+	fake1 = fake_superblock1();
+	if (fake1 == NULL) {
+		return "Failed allocating memory for test superblock 1";
+	}
+	
+	ASSERT_EQ_32(0x03020100, ext2_superblock_get_total_inode_count(fake1),
+	    "Failed getting total inode count");
+	ASSERT_EQ_32(0x07060504, ext2_superblock_get_total_block_count(fake1),
+	    "Failed getting total block count");
+	ASSERT_EQ_32(0x0B0A0908, ext2_superblock_get_reserved_block_count(fake1),
+	    "Failed getting reserved block count");
+	ASSERT_EQ_32(0x0F0E0D0C, ext2_superblock_get_free_block_count(fake1),
+	    "Failed getting free block count");
+	ASSERT_EQ_32(0x13121110, ext2_superblock_get_free_inode_count(fake1),
+	    "Failed getting free inode count");
+	ASSERT_EQ_32(0x17161514, ext2_superblock_get_first_block(fake1),
+	    "Failed getting first block number");
+	ASSERT_EQ_32(0x1B1A1918, ext2_superblock_get_block_size_log2(fake1),
+	    "Failed getting log block size");
+	ASSERT_EQ_32(0x1F1E1D1C, ext2_superblock_get_fragment_size_log2(fake1),
+	    "Failed getting log fragment size");
+	ASSERT_EQ_32(0x23222120, ext2_superblock_get_blocks_per_group(fake1),
+	    "Failed getting blocks per group");
+	ASSERT_EQ_32(0x27262524, ext2_superblock_get_fragments_per_group(fake1),
+	    "Failed getting fragments per group");
+	ASSERT_EQ_32(0x2B2A2928, ext2_superblock_get_inodes_per_group(fake1),
+	    "Failed getting inodes per group");
+	ASSERT_EQ_16(0x3938, ext2_superblock_get_magic(fake1),
+	    "Failed getting magic number");
+	ASSERT_EQ_16(0x3B3A, ext2_superblock_get_state(fake1),
+	    "Failed getting state");
+	ASSERT_EQ_16(0x3F3E, ext2_superblock_get_rev_minor(fake1),
+	    "Failed getting minor revision number");
+	ASSERT_EQ_32(0x4B4A4948, ext2_superblock_get_os(fake1),
+	    "Failed getting OS");
+	ASSERT_EQ_32(0x4F4E4D4C, ext2_superblock_get_rev_major(fake1),
+	    "Failed getting major revision number");
+	ASSERT_EQ_32(0x57565554, ext2_superblock_get_first_inode(fake1),
+	    "Failed getting first inode number");
+	ASSERT_EQ_16(0x5958, ext2_superblock_get_inode_size(fake1),
+	    "Failed getting size");
+	ASSERT_EQ_8(0x68, fake1->uuid[0], "UUID position is incorrect");
+	ASSERT_EQ_8(0x78, fake1->volume_name[0],
+	    "Volume name position is incorrect");
+	
+	return NULL;
+}
Index: uspace/app/tester/ext2/ext2_1.def
===================================================================
--- uspace/app/tester/ext2/ext2_1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/ext2/ext2_1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,6 @@
+{
+	"ext2_1",
+	"Superblock getters test",
+	&test_ext2_1,
+	true
+},
Index: uspace/app/tester/float/float1.c
===================================================================
--- uspace/app/tester/float/float1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/float/float1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2005 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <atomic.h>
+#include <thread.h>
+#include <inttypes.h>
+#include "../tester.h"
+
+#define THREADS   150
+#define ATTEMPTS  100
+
+#define E_10E8     UINT32_C(271828182)
+#define PRECISION  100000000
+
+static atomic_t threads_finished;
+static atomic_t threads_fault;
+
+static void e(void *data)
+{
+	for (unsigned int i = 0; i < ATTEMPTS; i++) {
+		double le = -1;
+		double e = 0;
+		double f = 1;
+		
+		for (double d = 1; e != le; d *= f, f += 1) {
+			le = e;
+			e = e + 1 / d;
+		}
+		
+		if ((uint32_t) (e * PRECISION) != E_10E8) {
+			atomic_inc(&threads_fault);
+			break;
+		}
+	}
+	
+	atomic_inc(&threads_finished);
+}
+
+const char *test_float1(void)
+{
+	atomic_count_t total = 0;
+	
+	atomic_set(&threads_finished, 0);
+	atomic_set(&threads_fault, 0);
+	
+	TPRINTF("Creating threads");
+	for (unsigned int i = 0; i < THREADS; i++) {
+		if (thread_create(e, NULL, "e", NULL) < 0) {
+			TPRINTF("\nCould not create thread %u\n", i);
+			break;
+		}
+		
+		TPRINTF(".");
+		total++;
+	}
+	
+	TPRINTF("\n");
+	
+	while (atomic_get(&threads_finished) < total) {
+		TPRINTF("Threads left: %" PRIua "\n",
+		    total - atomic_get(&threads_finished));
+		sleep(1);
+	}
+	
+	if (atomic_get(&threads_fault) == 0)
+		return NULL;
+	
+	return "Test failed";
+}
Index: uspace/app/tester/float/float1.def
===================================================================
--- uspace/app/tester/float/float1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/float/float1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,6 @@
+{
+	"float1",
+	"Floating point computation",
+	&test_float1,
+	true
+},
Index: uspace/app/tester/float/softfloat1.c
===================================================================
--- uspace/app/tester/float/softfloat1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/float/softfloat1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 Martin Decky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sftypes.h>
+#include <add.h>
+#include <bool.h>
+#include "../tester.h"
+
+#define OPERANDS   5
+#define PRECISION  10000
+
+#define PRIdCMPTYPE  PRId32
+
+typedef int32_t cmptype_t;
+
+static float float_op_a[OPERANDS] =
+	{3.5, -2.1, 100.0, 50.0, -1024.0};
+
+static float float_op_b[OPERANDS] =
+	{-2.1, 100.0, 50.0, -1024.0, 3.5};
+
+static cmptype_t cmpabs(cmptype_t a)
+{
+	if (a >= 0)
+		return a;
+	
+	return -a;
+}
+
+static bool test_float_add(void)
+{
+	bool correct = true;
+	
+	for (unsigned int i = 0; i < OPERANDS; i++) {
+		for (unsigned int j = 0; j < OPERANDS; j++) {
+			float a = float_op_a[i];
+			float b = float_op_b[j];
+			float c = a + b;
+			
+			float_t sa;
+			float_t sb;
+			float_t sc;
+			
+			sa.val = float_op_a[i];
+			sb.val = float_op_b[i];
+			sc.data = add_float(sa.data, sb.data);
+			
+			cmptype_t ic = (cmptype_t) (c * PRECISION);
+			cmptype_t isc = (cmptype_t) (sc.val * PRECISION);
+			cmptype_t diff = cmpabs(ic - isc);
+			
+			if (diff != 0) {
+				TPRINTF("i=%u, j=%u diff=%" PRIdCMPTYPE "\n", i, j, diff);
+				correct = false;
+			}
+		}
+	}
+	
+	return correct;
+}
+
+const char *test_softfloat1(void)
+{
+	if (!test_float_add())
+		return "Float addition failed";
+	
+	return NULL;
+}
Index: uspace/app/tester/float/softfloat1.def
===================================================================
--- uspace/app/tester/float/softfloat1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/float/softfloat1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,6 @@
+{
+	"softfloat1",
+	"Software floating point computation",
+	&test_softfloat1,
+	true
+},
Index: pace/app/tester/libext2/libext2_1.c
===================================================================
--- uspace/app/tester/libext2/libext2_1.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,106 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Sucha
- * 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.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include "../tester.h"
-#include "../util.h"
-#include <libext2.h>
-#include <malloc.h>
-
-static ext2_superblock_t *fake_superblock1()
-{
-	uint8_t *buf;
-	int i;
-	
-	buf = malloc(EXT2_SUPERBLOCK_SIZE);
-	if (buf == NULL) {
-		return NULL;
-	}
-	
-	for (i = 0; i < EXT2_SUPERBLOCK_SIZE; i++) {
-		buf[i] = i % 256;
-	}
-	
-	return (ext2_superblock_t *) buf;
-}
-
-const char *test_libext2_1(void)
-{
-	ext2_superblock_t *fake1;
-	
-	TPRINTF("Testing libext2 superblock getters...\n");
-	TPRINTF("Simple test for correct position and byte order\n");
-	
-	fake1 = fake_superblock1();
-	if (fake1 == NULL) {
-		return "Failed allocating memory for test superblock 1";
-	}
-	
-	ASSERT_EQ_32(0x03020100, ext2_superblock_get_total_inode_count(fake1),
-	    "Failed getting total inode count");
-	ASSERT_EQ_32(0x07060504, ext2_superblock_get_total_block_count(fake1),
-	    "Failed getting total block count");
-	ASSERT_EQ_32(0x0B0A0908, ext2_superblock_get_reserved_block_count(fake1),
-	    "Failed getting reserved block count");
-	ASSERT_EQ_32(0x0F0E0D0C, ext2_superblock_get_free_block_count(fake1),
-	    "Failed getting free block count");
-	ASSERT_EQ_32(0x13121110, ext2_superblock_get_free_inode_count(fake1),
-	    "Failed getting free inode count");
-	ASSERT_EQ_32(0x17161514, ext2_superblock_get_first_block(fake1),
-	    "Failed getting first block number");
-	ASSERT_EQ_32(0x1B1A1918, ext2_superblock_get_block_size_log2(fake1),
-	    "Failed getting log block size");
-	ASSERT_EQ_32(0x1F1E1D1C, ext2_superblock_get_fragment_size_log2(fake1),
-	    "Failed getting log fragment size");
-	ASSERT_EQ_32(0x23222120, ext2_superblock_get_blocks_per_group(fake1),
-	    "Failed getting blocks per group");
-	ASSERT_EQ_32(0x27262524, ext2_superblock_get_fragments_per_group(fake1),
-	    "Failed getting fragments per group");
-	ASSERT_EQ_32(0x2B2A2928, ext2_superblock_get_inodes_per_group(fake1),
-	    "Failed getting inodes per group");
-	ASSERT_EQ_16(0x3938, ext2_superblock_get_magic(fake1),
-	    "Failed getting magic number");
-	ASSERT_EQ_16(0x3B3A, ext2_superblock_get_state(fake1),
-	    "Failed getting state");
-	ASSERT_EQ_16(0x3F3E, ext2_superblock_get_rev_minor(fake1),
-	    "Failed getting minor revision number");
-	ASSERT_EQ_32(0x4B4A4948, ext2_superblock_get_os(fake1),
-	    "Failed getting OS");
-	ASSERT_EQ_32(0x4F4E4D4C, ext2_superblock_get_rev_major(fake1),
-	    "Failed getting major revision number");
-	ASSERT_EQ_32(0x57565554, ext2_superblock_get_first_inode(fake1),
-	    "Failed getting first inode number");
-	ASSERT_EQ_16(0x5958, ext2_superblock_get_inode_size(fake1),
-	    "Failed getting size");
-	ASSERT_EQ_8(0x68, fake1->uuid[0], "UUID position is incorrect");
-	ASSERT_EQ_8(0x78, fake1->volume_name[0],
-	    "Volume name position is incorrect");
-	
-	return NULL;
-}
Index: pace/app/tester/libext2/libext2_1.def
===================================================================
--- uspace/app/tester/libext2/libext2_1.def	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,6 +1,0 @@
-{
-	"libext2_1",
-	"Superblock getters test",
-	&test_libext2_1,
-	true
-},
Index: uspace/app/tester/stdio/logger1.c
===================================================================
--- uspace/app/tester/stdio/logger1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/stdio/logger1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <io/log.h>
+#include "../tester.h"
+
+const char *test_logger1(void)
+{
+	for (log_level_t level = 0; level < LVL_LIMIT; level++) {
+		log_msg(LOG_DEFAULT, level, "Testing logger, level %d.", (int) level);
+	}
+
+	return NULL;
+}
Index: uspace/app/tester/stdio/logger1.def
===================================================================
--- uspace/app/tester/stdio/logger1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/stdio/logger1.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,6 @@
+{
+	"logger1",
+	"Logger printing test",
+	&test_logger1,
+	true
+},
Index: uspace/app/tester/stdio/logger2.c
===================================================================
--- uspace/app/tester/stdio/logger2.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/stdio/logger2.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <io/log.h>
+#include <async.h>
+#include "../tester.h"
+
+const char *test_logger2(void)
+{
+	log_t log_alpha = log_create("alpha", LOG_DEFAULT);
+	log_t log_bravo = log_create("bravo", log_alpha);
+
+	TPRINTF("Alpha is %" PRIlogctx ".\n", log_alpha);
+	TPRINTF("Bravo is %" PRIlogctx ".\n", log_bravo);
+
+	while (true) {
+		/*
+		 * Intentionally skipping FATAL to allow muting
+		 * the output completely by setting visible level to FATAL.
+		 */
+		for (log_level_t level = LVL_ERROR; level < LVL_LIMIT; level++) {
+			log_msg(LOG_DEFAULT, level, "Printing level %d (%s).",
+			    (int) level, log_level_str(level));
+			log_msg(log_alpha, level,
+			    "Printing level %d (%s) into alpha log.",
+			    (int) level, log_level_str(level));
+			log_msg(log_bravo, level,
+			    "Printing level %d (%s) into bravo sub-log.",
+			    (int) level, log_level_str(level));
+			async_usleep(1000 * 100);
+		}
+	}
+
+	return NULL;
+}
Index: uspace/app/tester/stdio/logger2.def
===================================================================
--- uspace/app/tester/stdio/logger2.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/app/tester/stdio/logger2.def	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,6 @@
+{
+	"logger2",
+	"Logger endless test",
+	&test_logger2,
+	false
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/app/tester/tester.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <str.h>
+#include <io/log.h>
 #include "tester.h"
 
@@ -55,7 +56,11 @@
 #include "stdio/stdio1.def"
 #include "stdio/stdio2.def"
+#include "stdio/logger1.def"
+#include "stdio/logger2.def"
 #include "fault/fault1.def"
 #include "fault/fault2.def"
 #include "fault/fault3.def"
+#include "float/float1.def"
+#include "float/softfloat1.def"
 #include "vfs/vfs1.def"
 #include "ipc/ping_pong.def"
@@ -68,5 +73,5 @@
 #include "hw/serial/serial1.def"
 #include "hw/misc/virtchar1.def"
-#include "libext2/libext2_1.def"
+#include "ext2/ext2_1.def"
 	{NULL, NULL, NULL, false}
 };
@@ -138,4 +143,6 @@
 	}
 	
+	log_init("tester");
+
 	test_quiet = false;
 	test_argc = argc - 2;
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/app/tester/tester.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -88,7 +88,11 @@
 extern const char *test_stdio1(void);
 extern const char *test_stdio2(void);
+extern const char *test_logger1(void);
+extern const char *test_logger2(void);
 extern const char *test_fault1(void);
 extern const char *test_fault2(void);
 extern const char *test_fault3(void);
+extern const char *test_float1(void);
+extern const char *test_softfloat1(void);
 extern const char *test_vfs1(void);
 extern const char *test_ping_pong(void);
@@ -101,5 +105,5 @@
 extern const char *test_serial1(void);
 extern const char *test_virtchar1(void);
-extern const char *test_libext2_1(void);
+extern const char *test_ext2_1(void);
 extern const char *test_devman1(void);
 extern const char *test_devman2(void);
Index: uspace/app/vuhid/main.c
===================================================================
--- uspace/app/vuhid/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/app/vuhid/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -155,5 +155,5 @@
 	int rc;
 
-	usb_log_enable(USB_LOG_LEVEL_DEBUG2, "vusbhid");
+	log_init("vuhid");
 
 	fibril_mutex_initialize(&vuhid_data.iface_count_mutex);
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/block/ahci/ahci.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -1340,5 +1340,5 @@
 {
 	printf("%s: HelenOS AHCI device driver\n", NAME);
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	fibril_mutex_initialize(&sata_devices_count_lock);
 	return ddf_driver_main(&ahci_driver);
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/isa/isa.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -712,5 +712,5 @@
 static void isa_init()
 {
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	isa_fun_ops.interfaces[HW_RES_DEV_IFACE] = &isa_fun_hw_res_ops;
 }
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -729,5 +729,5 @@
 static void pciintel_init(void)
 {
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops;
 	pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;
Index: uspace/drv/bus/usb/ehci/main.c
===================================================================
--- uspace/drv/bus/usb/ehci/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/ehci/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -132,5 +132,5 @@
 int main(int argc, char *argv[])
 {
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 	return ddf_driver_main(&ehci_driver);
 }
Index: uspace/drv/bus/usb/ohci/main.c
===================================================================
--- uspace/drv/bus/usb/ohci/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/ohci/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -83,5 +83,5 @@
 int main(int argc, char *argv[])
 {
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 	return ddf_driver_main(&ohci_driver);
 }
Index: uspace/drv/bus/usb/uhci/main.c
===================================================================
--- uspace/drv/bus/usb/uhci/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/uhci/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -87,5 +87,5 @@
 {
 	printf(NAME ": HelenOS UHCI driver.\n");
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return ddf_driver_main(&uhci_driver);
Index: uspace/drv/bus/usb/uhcirh/main.c
===================================================================
--- uspace/drv/bus/usb/uhcirh/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/uhcirh/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -73,5 +73,5 @@
 {
 	printf(NAME ": HelenOS UHCI root hub driver.\n");
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 	return ddf_driver_main(&uhci_rh_driver);
 }
Index: uspace/drv/bus/usb/usbflbk/main.c
===================================================================
--- uspace/drv/bus/usb/usbflbk/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/usbflbk/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -110,5 +110,5 @@
 int main(int argc, char *argv[])
 {
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return usb_driver_main(&usbfallback_driver);
Index: uspace/drv/bus/usb/usbhid/main.c
===================================================================
--- uspace/drv/bus/usb/usbhid/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/usbhid/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -172,5 +172,5 @@
 	printf(NAME ": HelenOS USB HID driver.\n");
 
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return usb_driver_main(&usb_hid_driver);
Index: uspace/drv/bus/usb/usbhub/main.c
===================================================================
--- uspace/drv/bus/usb/usbhub/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/usbhub/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -79,5 +79,5 @@
 {
 	printf(NAME ": HelenOS USB hub driver.\n");
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return usb_driver_main(&usb_hub_driver);
Index: uspace/drv/bus/usb/usbmast/main.c
===================================================================
--- uspace/drv/bus/usb/usbmast/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/usbmast/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -383,5 +383,5 @@
 int main(int argc, char *argv[])
 {
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return usb_driver_main(&usbmast_driver);
Index: uspace/drv/bus/usb/usbmid/main.c
===================================================================
--- uspace/drv/bus/usb/usbmid/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/usbmid/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -180,5 +180,5 @@
 	printf(NAME ": USB multi interface device driver.\n");
 
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	return usb_driver_main(&mid_driver);
Index: uspace/drv/bus/usb/vhc/Makefile
===================================================================
--- uspace/drv/bus/usb/vhc/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/vhc/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -32,6 +32,6 @@
 	$(LIBUSBDEV_PREFIX)/libusbdev.a \
 	$(LIBUSBHOST_PREFIX)/libusbhost.a \
+	$(LIBUSBVIRT_PREFIX)/libusbvirt.a \
 	$(LIBUSB_PREFIX)/libusb.a \
-	$(LIBUSBVIRT_PREFIX)/libusbvirt.a \
 	$(LIBDRV_PREFIX)/libdrv.a
 
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/bus/usb/vhc/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -138,5 +138,5 @@
 int main(int argc, char * argv[])
 {	
-	usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME);
+	log_init(NAME);
 
 	printf(NAME ": virtual USB host controller driver.\n");
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/char/i8042/i8042.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -302,5 +302,5 @@
 	const bool enabled = hw_res_enable_interrupt(parent_sess);
 	if (!enabled) {
-		log_msg(LVL_ERROR, "Failed to enable interrupts: %s.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to enable interrupts: %s.",
 		    ddf_dev_get_name(ddf_dev));
 		rc = EIO;
Index: uspace/drv/char/i8042/main.c
===================================================================
--- uspace/drv/char/i8042/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/char/i8042/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -151,5 +151,5 @@
 {
 	printf("%s: HelenOS PS/2 driver.\n", NAME);
-	ddf_log_init(NAME, LVL_NOTE);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&i8042_driver);
 }
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/char/ns8250/ns8250.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -1084,5 +1084,5 @@
 static void ns8250_init(void)
 {
-	ddf_log_init(NAME, LVL_WARN);
+	ddf_log_init(NAME);
 	
 	ns8250_dev_ops.open = &ns8250_open;
Index: uspace/drv/char/ps2mouse/main.c
===================================================================
--- uspace/drv/char/ps2mouse/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/char/ps2mouse/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -69,5 +69,5 @@
 {
 	printf(NAME ": HelenOS ps/2 mouse driver.\n");
-	ddf_log_init(NAME, LVL_NOTE);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&mouse_driver);
 }
Index: uspace/drv/char/xtkbd/main.c
===================================================================
--- uspace/drv/char/xtkbd/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/char/xtkbd/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -69,5 +69,5 @@
 {
 	printf(NAME ": HelenOS XT keyboard driver.\n");
-	ddf_log_init(NAME, LVL_NOTE);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&kbd_driver);
 }
Index: uspace/drv/infrastructure/root/root.c
===================================================================
--- uspace/drv/infrastructure/root/root.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/infrastructure/root/root.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -237,5 +237,5 @@
 	printf(NAME ": HelenOS root device driver\n");
 
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&root_driver);
 }
Index: uspace/drv/infrastructure/rootmac/rootmac.c
===================================================================
--- uspace/drv/infrastructure/rootmac/rootmac.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/infrastructure/rootmac/rootmac.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -179,5 +179,5 @@
 {
 	printf("%s: HelenOS Mac platform driver\n", NAME);
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	rootmac_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
 	return ddf_driver_main(&rootmac_driver);
Index: uspace/drv/infrastructure/rootpc/rootpc.c
===================================================================
--- uspace/drv/infrastructure/rootpc/rootpc.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/infrastructure/rootpc/rootpc.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -195,5 +195,5 @@
 static void root_pc_init(void)
 {
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	rootpc_fun_ops.interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops;
 }
Index: uspace/drv/infrastructure/rootvirt/rootvirt.c
===================================================================
--- uspace/drv/infrastructure/rootvirt/rootvirt.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/infrastructure/rootvirt/rootvirt.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -240,5 +240,5 @@
 	printf(NAME ": HelenOS virtual devices root driver\n");
 
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&rootvirt_driver);
 }
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/nic/e1k/e1k.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -2381,5 +2381,5 @@
 	    &e1000_nic_iface);
 	
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	ddf_msg(LVL_NOTE, "HelenOS E1000 driver started");
 	return ddf_driver_main(&e1000_driver);
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/nic/rtl8139/driver.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -2187,5 +2187,5 @@
 		&rtl8139_driver_ops, &rtl8139_dev_ops, &rtl8139_nic_iface);
 
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	ddf_msg(LVL_NOTE, "HelenOS RTL8139 driver started");
 	return ddf_driver_main(&rtl8139_driver);
Index: uspace/drv/test/test1/test1.c
===================================================================
--- uspace/drv/test/test1/test1.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/test/test1/test1.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -306,5 +306,5 @@
 {
 	printf(NAME ": HelenOS test1 virtual device driver\n");
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&test1_driver);
 }
Index: uspace/drv/test/test2/test2.c
===================================================================
--- uspace/drv/test/test2/test2.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/test/test2/test2.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -308,5 +308,5 @@
 {
 	printf(NAME ": HelenOS test2 virtual device driver\n");
-	ddf_log_init(NAME, LVL_NOTE);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&test2_driver);
 }
Index: uspace/drv/test/test3/test3.c
===================================================================
--- uspace/drv/test/test3/test3.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/drv/test/test3/test3.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -193,5 +193,5 @@
 {
 	printf(NAME ": HelenOS test3 virtual device driver\n");
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME);
 	return ddf_driver_main(&test3_driver);
 }
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -103,4 +103,5 @@
 	generic/io/printf.c \
 	generic/io/log.c \
+	generic/io/logctl.c \
 	generic/io/klog.c \
 	generic/io/snprintf.c \
Index: uspace/lib/c/arch/abs32le/_link.ld.in
===================================================================
--- uspace/lib/c/arch/abs32le/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/abs32le/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -15,14 +15,7 @@
 #ifdef LOADER
 	. = 0x70001000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x1000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.text : {
@@ -30,4 +23,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x1000;
Index: uspace/lib/c/arch/amd64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/amd64/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/amd64/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -16,14 +16,7 @@
 #ifdef LOADER
 	. = 0x70001000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x1000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.init : {
@@ -35,4 +28,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x1000;
Index: uspace/lib/c/arch/arm32/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.common	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/arm32/Makefile.common	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -28,6 +28,6 @@
 #
 
-GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -march=armv4
 BASE_LIBS += $(LIBSOFTFLOAT_PREFIX)/libsoftfloat.a
+GCC_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -march=armv4 -mapcs-frame
 
 ENDIANESS = LE
Index: uspace/lib/c/arch/arm32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/arm32/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/arm32/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -15,14 +15,7 @@
 #ifdef LOADER
 	. = 0x70001000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x1000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 8);
 	
 	.init : {
@@ -34,4 +27,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x1000;
Index: uspace/lib/c/arch/ia32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ia32/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/ia32/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -24,13 +24,4 @@
 	. = 0x1000 + SIZEOF_HEADERS;
 #endif
-	
-#if defined(LOADER) || defined(DLEXE)
-	.interp : {
-		*(.interp);
-	} :interp :text
-#endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.init : {
@@ -71,4 +62,11 @@
 	} :text
 #endif
+	
+#if defined(LOADER) || defined(DLEXE)
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
+	
 	. = . + 0x1000;
 	
Index: uspace/lib/c/arch/ia64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ia64/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/ia64/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -15,13 +15,9 @@
 #ifdef LOADER
 	. = 0x800000000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x4000 + SIZEOF_HEADERS;
 #endif
 	
-	/* Make sure the code is aligned reasonably */
+	/* Workaround proper alignment of the .init section */
 	. = ALIGN(., 16);
 	
@@ -34,4 +30,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x4000;
Index: uspace/lib/c/arch/mips32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips32/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/mips32/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -15,14 +15,7 @@
 #ifdef LOADER
 	. = 0x70004000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x4000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.init : {
@@ -34,4 +27,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x4000;
Index: uspace/lib/c/arch/mips64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/mips64/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/mips64/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -16,14 +16,7 @@
 #ifdef LOADER
 	. = 0x70004000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x4000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.init : {
@@ -35,4 +28,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x4000;
Index: uspace/lib/c/arch/ppc32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ppc32/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/ppc32/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -16,14 +16,7 @@
 #ifdef LOADER
 	. = 0x70001000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x1000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 4);
 	
 	.init : {
@@ -35,4 +28,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x1000;
Index: uspace/lib/c/arch/sparc64/_link.ld.in
===================================================================
--- uspace/lib/c/arch/sparc64/_link.ld.in	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/arch/sparc64/_link.ld.in	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -15,14 +15,7 @@
 #ifdef LOADER
 	. = 0x70004000 + SIZEOF_HEADERS;
-	
-	.interp : {
-		*(.interp);
-	} :interp :text
 #else
 	. = 0x4000 + SIZEOF_HEADERS;
 #endif
-	
-	/* Make sure the code is aligned reasonably */
-	. = ALIGN(., 16);
 	
 	.init : {
@@ -34,4 +27,10 @@
 		*(.rodata .rodata.*);
 	} :text
+	
+#ifdef LOADER
+	.interp : {
+		*(.interp);
+	} :interp :text
+#endif
 	
 	. = . + 0x4000;
Index: uspace/lib/c/generic/io/log.c
===================================================================
--- uspace/lib/c/generic/io/log.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/generic/io/log.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -38,58 +38,190 @@
 #include <stdlib.h>
 #include <stdio.h>
-
+#include <async.h>
 #include <io/log.h>
-
-/** Serialization mutex for logging functions. */
-static FIBRIL_MUTEX_INITIALIZE(log_serializer);
-
-/** Current log level. */
-static log_level_t log_level;
-
-static FILE *log_stream;
-
+#include <ipc/logger.h>
+#include <ns.h>
+
+/** Id of the first log we create at logger. */
+static sysarg_t default_log_id;
+
+/** Log messages are printed under this name. */
 static const char *log_prog_name;
 
-/** Prefixes for individual logging levels. */
+/** Names of individual log levels. */
 static const char *log_level_names[] = {
-	[LVL_FATAL] = "Fatal error",
-	[LVL_ERROR] = "Error",
-	[LVL_WARN] = "Warning",
-	[LVL_NOTE] = "Note",
-	[LVL_DEBUG] = "Debug",
-	[LVL_DEBUG2] = "Debug2"
+	"fatal",
+	"error",
+	"warn",
+	"note",
+	"debug",
+	"debug2",
+	NULL
 };
 
+/** IPC session with the logger service. */
+static async_sess_t *logger_session;
+
+/** Maximum length of a single log message (in bytes). */
+#define MESSAGE_BUFFER_SIZE 4096
+
+/** Send formatted message to the logger service.
+ *
+ * @param session Initialized IPC session with the logger.
+ * @param log Log to use.
+ * @param level Verbosity level of the message.
+ * @param message The actual message.
+ * @return Error code of the conversion or EOK on success.
+ */
+static int logger_message(async_sess_t *session, log_t log, log_level_t level, char *message)
+{
+	async_exch_t *exchange = async_exchange_begin(session);
+	if (exchange == NULL) {
+		return ENOMEM;
+	}
+	if (log == LOG_DEFAULT)
+		log = default_log_id;
+
+	// FIXME: remove when all USB drivers use libc logging explicitly
+	str_rtrim(message, '\n');
+
+	aid_t reg_msg = async_send_2(exchange, LOGGER_WRITER_MESSAGE,
+	    log, level, NULL);
+	int rc = async_data_write_start(exchange, message, str_size(message));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	/*
+	 * Getting ENAK means no-one wants our message. That is not an
+	 * error at all.
+	 */
+	if (rc == ENAK)
+		rc = EOK;
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	return reg_msg_rc;
+}
+
+/** Get name of the log level.
+ *
+ * @param level The log level.
+ * @return String name or "unknown".
+ */
+const char *log_level_str(log_level_t level)
+{
+	if (level >= LVL_LIMIT)
+		return "unknown";
+	else
+		return log_level_names[level];
+}
+
+/** Convert log level name to the enum.
+ *
+ * @param[in] name Log level name or log level number.
+ * @param[out] level_out Where to store the result (set to NULL to ignore).
+ * @return Error code of the conversion or EOK on success.
+ */
+int log_level_from_str(const char *name, log_level_t *level_out)
+{
+	log_level_t level = LVL_FATAL;
+
+	while (log_level_names[level] != NULL) {
+		if (str_cmp(name, log_level_names[level]) == 0) {
+			if (level_out != NULL)
+				*level_out = level;
+			return EOK;
+		}
+		level++;
+	}
+
+	/* Maybe user specified number directly. */
+	char *end_ptr;
+	int level_int = strtol(name, &end_ptr, 0);
+	if ((end_ptr == name) || (str_length(end_ptr) != 0))
+		return EINVAL;
+	if (level_int < 0)
+		return ERANGE;
+	if (level_int >= (int) LVL_LIMIT)
+		return ERANGE;
+
+	if (level_out != NULL)
+		*level_out = (log_level_t) level_int;
+
+	return EOK;
+}
+
 /** Initialize the logging system.
  *
- * @param prog_name	Program name, will be printed as part of message
- * @param level		Minimum message level to print
- */
-int log_init(const char *prog_name, log_level_t level)
-{
-	assert(level < LVL_LIMIT);
-	log_level = level;
-
-	log_stream = stdout;
+ * @param prog_name Program name, will be printed as part of message
+ */
+int log_init(const char *prog_name)
+{
 	log_prog_name = str_dup(prog_name);
 	if (log_prog_name == NULL)
 		return ENOMEM;
 
+	logger_session = service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOGGER, LOGGER_INTERFACE_WRITER, 0);
+	if (logger_session == NULL) {
+		return ENOMEM;
+	}
+
+	default_log_id = log_create(prog_name, LOG_NO_PARENT);
+
 	return EOK;
 }
 
+/** Create a new (sub-) log.
+ *
+ * This function always returns a valid log_t. In case of errors,
+ * @c parent is returned and errors are silently ignored.
+ *
+ * @param name Log name under which message will be reported (appended to parents name).
+ * @param parent Parent log.
+ * @return Opaque identifier of the newly created log.
+ */
+log_t log_create(const char *name, log_t parent)
+{
+	async_exch_t *exchange = async_exchange_begin(logger_session);
+	if (exchange == NULL)
+		return parent;
+
+	if (parent == LOG_DEFAULT)
+		parent = default_log_id;
+
+	ipc_call_t answer;
+	aid_t reg_msg = async_send_1(exchange, LOGGER_WRITER_CREATE_LOG,
+	    parent, &answer);
+	int rc = async_data_write_start(exchange, name, str_size(name));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	if ((rc != EOK) || (reg_msg_rc != EOK))
+		return parent;
+
+	return IPC_GET_ARG1(answer);
+}
+
 /** Write an entry to the log.
  *
- * @param level		Message verbosity level. Message is only printed
- *			if verbosity is less than or equal to current
- *			reporting level.
- * @param fmt		Format string (no traling newline).
- */
-void log_msg(log_level_t level, const char *fmt, ...)
+ * The message is printed only if the verbosity level is less than or
+ * equal to currently set reporting level of the log.
+ *
+ * @param ctx Log to use (use LOG_DEFAULT if you have no idea what it means).
+ * @param level Severity level of the message.
+ * @param fmt Format string in printf-like format (without trailing newline).
+ */
+void log_msg(log_t ctx, log_level_t level, const char *fmt, ...)
 {
 	va_list args;
 
 	va_start(args, fmt);
-	log_msgv(level, fmt, args);
+	log_msgv(ctx, level, fmt, args);
 	va_end(args);
 }
@@ -97,25 +229,20 @@
 /** Write an entry to the log (va_list variant).
  *
- * @param level		Message verbosity level. Message is only printed
- *			if verbosity is less than or equal to current
- *			reporting level.
- * @param fmt		Format string (no trailing newline)
- */
-void log_msgv(log_level_t level, const char *fmt, va_list args)
+ * @param ctx Log to use (use LOG_DEFAULT if you have no idea what it means).
+ * @param level Severity level of the message.
+ * @param fmt Format string in printf-like format (without trailing newline).
+ * @param args Arguments.
+ */
+void log_msgv(log_t ctx, log_level_t level, const char *fmt, va_list args)
 {
 	assert(level < LVL_LIMIT);
 
-	/* Higher number means higher verbosity. */
-	if (level <= log_level) {
-		fibril_mutex_lock(&log_serializer);
-
-		fprintf(log_stream, "%s: %s: ", log_prog_name,
-		    log_level_names[level]);
-		vfprintf(log_stream, fmt, args);
-		fputc('\n', log_stream);
-		fflush(log_stream);
-
-		fibril_mutex_unlock(&log_serializer);
-	}
+	char *message_buffer = malloc(MESSAGE_BUFFER_SIZE);
+	if (message_buffer == NULL) {
+		return;
+	}
+
+	vsnprintf(message_buffer, MESSAGE_BUFFER_SIZE, fmt, args);
+	logger_message(logger_session, ctx, level, message_buffer);
 }
 
Index: uspace/lib/c/generic/io/logctl.c
===================================================================
--- uspace/lib/c/generic/io/logctl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/c/generic/io/logctl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 libc
+ * @{
+ */
+
+#include <assert.h>
+#include <unistd.h>
+#include <errno.h>
+#include <io/logctl.h>
+#include <ipc/logger.h>
+#include <sysinfo.h>
+#include <ns.h>
+#include <str.h>
+
+/** IPC session with the logger service. */
+static async_sess_t *logger_session = NULL;
+
+static int start_logger_exchange(async_exch_t **exchange_out)
+{
+	assert(exchange_out != NULL);
+
+	if (logger_session == NULL) {
+		logger_session = service_connect_blocking(EXCHANGE_SERIALIZE,
+		    SERVICE_LOGGER, LOGGER_INTERFACE_CONTROL, 0);
+		if (logger_session == NULL)
+			return ENOMEM;
+	}
+
+	assert(logger_session != NULL);
+
+	async_exch_t *exchange = async_exchange_begin(logger_session);
+	if (exchange == NULL)
+		return ENOMEM;
+
+	*exchange_out = exchange;
+
+	return EOK;
+}
+
+/** Set default reported log level (global setting).
+ *
+ * This setting affects all logger clients whose reporting level was
+ * not yet changed.
+ *
+ * If logging level of client A is changed with logctl_set_log_level()
+ * to some level, this call will have no effect at that client's reporting
+ * level. Even if the actual value of the reporting level of client A is
+ * the same as current (previous) default log level.
+ *
+ * @param new_level New reported logging level.
+ * @return Error code of the conversion or EOK on success.
+ */
+int logctl_set_default_level(log_level_t new_level)
+{
+	async_exch_t *exchange = NULL;
+	int rc = start_logger_exchange(&exchange);
+	if (rc != EOK)
+		return rc;
+
+	rc = (int) async_req_1_0(exchange,
+	    LOGGER_CONTROL_SET_DEFAULT_LEVEL, new_level);
+
+	async_exchange_end(exchange);
+
+	return rc;
+}
+
+/** Set reported log level of a single log.
+ *
+ * @see logctl_set_default_level
+ *
+ * @param logname Log name.
+ * @param new_level New reported logging level.
+ * @return Error code of the conversion or EOK on success.
+ */
+int logctl_set_log_level(const char *logname, log_level_t new_level)
+{
+	async_exch_t *exchange = NULL;
+	int rc = start_logger_exchange(&exchange);
+	if (rc != EOK)
+		return rc;
+
+	aid_t reg_msg = async_send_1(exchange, LOGGER_CONTROL_SET_LOG_LEVEL,
+	    new_level, NULL);
+	rc = async_data_write_start(exchange, logname, str_size(logname));
+	sysarg_t reg_msg_rc;
+	async_wait_for(reg_msg, &reg_msg_rc);
+
+	async_exchange_end(exchange);
+
+	if (rc != EOK)
+		return rc;
+
+	return (int) reg_msg_rc;
+}
+
+/** @}
+ */
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/include/io/log.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -36,12 +36,20 @@
 
 #include <stdarg.h>
+#include <inttypes.h>
 #include <io/verify.h>
 
+/** Log message level. */
 typedef enum {
+	/** Fatal error, program is not able to recover at all. */
 	LVL_FATAL,
+	/** Serious error but the program can recover from it. */
 	LVL_ERROR,
+	/** Easily recoverable problem. */
 	LVL_WARN,
+	/** Information message that ought to be printed by default. */
 	LVL_NOTE,
+	/** Debugging purpose message. */
 	LVL_DEBUG,
+	/** More detailed debugging message. */
 	LVL_DEBUG2,
 	
@@ -50,8 +58,24 @@
 } log_level_t;
 
-extern int log_init(const char *, log_level_t);
-extern void log_msg(log_level_t, const char *, ...)
-    PRINTF_ATTRIBUTE(2, 3);
-extern void log_msgv(log_level_t, const char *, va_list);
+/** Log itself (logging target). */
+typedef sysarg_t log_t;
+/** Formatting directive for printing log_t. */
+#define PRIlogctx PRIxn
+
+/** Default log (target). */
+#define LOG_DEFAULT ((log_t) -1)
+
+/** Use when creating new top-level log. */
+#define LOG_NO_PARENT ((log_t) 0)
+
+extern const char *log_level_str(log_level_t);
+extern int log_level_from_str(const char *, log_level_t *);
+
+extern int log_init(const char *);
+extern log_t log_create(const char *, log_t);
+
+extern void log_msg(log_t, log_level_t, const char *, ...)
+    PRINTF_ATTRIBUTE(3, 4);
+extern void log_msgv(log_t, log_level_t, const char *, va_list);
 
 #endif
Index: uspace/lib/c/include/io/logctl.h
===================================================================
--- uspace/lib/c/include/io/logctl.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/c/include/io/logctl.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011-2012 Vojtech Horky
+ * 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 libc
+ * @{
+ */
+
+#ifndef LIBC_IO_LOGCTL_H_
+#define LIBC_IO_LOGCTL_H_
+
+#include <io/log.h>
+
+extern int logctl_set_default_level(log_level_t);
+extern int logctl_set_log_level(const char *, log_level_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/logger.h
===================================================================
--- uspace/lib/c/include/ipc/logger.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/c/include/ipc/logger.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 libc
+ * @{
+ */
+
+#ifndef LIBC_IPC_LOGGER_H_
+#define LIBC_IPC_LOGGER_H_
+
+#include <ipc/common.h>
+
+typedef enum {
+	/** Set (global) default displayed logging level.
+	 *
+	 * Arguments: new log level.
+	 * Returns: error code
+	 */
+	LOGGER_CONTROL_SET_DEFAULT_LEVEL = IPC_FIRST_USER_METHOD,
+	/** Set displayed level for given log.
+	 *
+	 * Arguments: new log level.
+	 * Returns: error code
+	 * Followed by: string with full log name.
+	 */
+	LOGGER_CONTROL_SET_LOG_LEVEL
+} logger_control_request_t;
+
+typedef enum {
+	/** Create new log.
+	 *
+	 * Arguments: parent log id (0 for top-level log).
+	 * Returns: error code, log id
+	 * Followed by: string with log name.
+	 */
+	LOGGER_WRITER_CREATE_LOG = IPC_FIRST_USER_METHOD,
+	/** Write a message to a given log.
+	 *
+	 * Arguments: log id, message severity level (log_level_t)
+	 * Returns: error code
+	 * Followed by: string with the message.
+	 */
+	LOGGER_WRITER_MESSAGE
+} logger_writer_request_t;
+
+typedef enum {
+	/** Interface for controlling logger behavior. */
+	LOGGER_INTERFACE_CONTROL,
+	/** Interface for servers writing to the log. */
+	LOGGER_INTERFACE_WRITER
+} logger_interface_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/c/include/ipc/services.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -45,4 +45,5 @@
 	SERVICE_VFS        = FOURCC('v', 'f', 's', ' '),
 	SERVICE_LOC        = FOURCC('l', 'o', 'c', ' '),
+	SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
 	SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
 	SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
Index: uspace/lib/drv/generic/log.c
===================================================================
--- uspace/lib/drv/generic/log.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/drv/generic/log.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -38,10 +38,9 @@
  *
  * @param drv_name Driver name, will be printed as part of message
- * @param level    Minimum message level to print
  *
  */
-int ddf_log_init(const char *drv_name, log_level_t level)
+int ddf_log_init(const char *drv_name)
 {
-	return log_init(drv_name, level);
+	return log_init(drv_name);
 }
 
@@ -59,5 +58,5 @@
 	
 	va_start(args, fmt);
-	log_msgv(level, fmt, args);
+	log_msgv(LOG_DEFAULT, level, fmt, args);
 	va_end(args);
 }
Index: uspace/lib/drv/include/ddf/log.h
===================================================================
--- uspace/lib/drv/include/ddf/log.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/drv/include/ddf/log.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -37,5 +37,5 @@
 #include <io/verify.h>
 
-extern int ddf_log_init(const char *, log_level_t);
+extern int ddf_log_init(const char *);
 extern void ddf_msg(log_level_t, const char *, ...)
     PRINTF_ATTRIBUTE(2, 3);
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/fs/libfs.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -631,12 +631,7 @@
 						async_answer_0(rid, rc);
 					} else {
-						aoff64_t size = ops->size_get(fn);
-						async_answer_5(rid, fs_handle,
-						    service_id,
-						    ops->index_get(fn),
-						    LOWER32(size),
-						    UPPER32(size),
-						    ops->lnkcnt_get(fn));
-						(void) ops->node_put(fn);
+						(void) ops->node_put(cur);
+						cur = fn;
+						goto out_with_answer;
 					}
 				} else
@@ -715,12 +710,7 @@
 					async_answer_0(rid, rc);
 				} else {
-					aoff64_t size = ops->size_get(fn);
-					async_answer_5(rid, fs_handle,
-					    service_id,
-					    ops->index_get(fn),
-					    LOWER32(size),
-					    UPPER32(size),
-					    ops->lnkcnt_get(fn));
-					(void) ops->node_put(fn);
+					(void) ops->node_put(cur);
+					cur = fn;
+					goto out_with_answer;
 				}
 			} else
Index: uspace/lib/softfloat/Makefile
===================================================================
--- uspace/lib/softfloat/Makefile	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/softfloat/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -29,17 +29,16 @@
 
 USPACE_PREFIX = ../..
-EXTRA_CFLAGS = -Iinclude
 LIBRARY = libsoftfloat
 
 SOURCES = \
-	generic/add.c \
-	generic/common.c \
-	generic/comparison.c \
-	generic/conversion.c \
-	generic/div.c \
-	generic/mul.c \
-	generic/other.c \
-	generic/softfloat.c \
-	generic/sub.c
+	softfloat.c \
+	common.c \
+	add.c \
+	sub.c \
+	div.c \
+	mul.c \
+	comparison.c \
+	conversion.c \
+	other.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/softfloat/add.c
===================================================================
--- uspace/lib/softfloat/add.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/add.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,416 @@
+/*
+ * 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 Addition functions.
+ */
+
+#include "sftypes.h"
+#include "add.h"
+#include "comparison.h"
+#include "common.h"
+
+/** Add two single-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ * @return Result of addition.
+ */
+float32 add_float32(float32 a, float32 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2, frac1, frac2;
+	
+	expdiff = a.parts.exp - b.parts.exp;
+	if (expdiff < 0) {
+		if (is_float32_nan(b)) {
+			/* TODO: fix SigNaN */
+			if (is_float32_signan(b)) {
+			}
+
+			return b;
+		}
+		
+		if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 
+			return b;
+		}
+		
+		frac1 = b.parts.fraction;
+		exp1 = b.parts.exp;
+		frac2 = a.parts.fraction;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if ((is_float32_nan(a)) || (is_float32_nan(b))) {
+			/* TODO: fix SigNaN */
+			if (is_float32_signan(a) || is_float32_signan(b)) {
+			}
+			return (is_float32_nan(a) ? a : b);
+		}
+		
+		if (a.parts.exp == FLOAT32_MAX_EXPONENT) { 
+			return a;
+		}
+		
+		frac1 = a.parts.fraction;
+		exp1 = a.parts.exp;
+		frac2 = b.parts.fraction;
+		exp2 = b.parts.exp;
+	}
+	
+	if (exp1 == 0) {
+		/* both are denormalized */
+		frac1 += frac2;
+		if (frac1 & FLOAT32_HIDDEN_BIT_MASK ) {
+			/* result is not denormalized */
+			a.parts.exp = 1;
+		}
+		a.parts.fraction = frac1;
+		return a;
+	}
+	
+	frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
+
+	if (exp2 == 0) {
+		/* second operand is denormalized */
+		--expdiff;
+	} else {
+		/* add hidden bit to second operand */
+		frac2 |= FLOAT32_HIDDEN_BIT_MASK; 
+	}
+	
+	/* create some space for rounding */
+	frac1 <<= 6;
+	frac2 <<= 6;
+	
+	if (expdiff < (FLOAT32_FRACTION_SIZE + 2) ) {
+		frac2 >>= expdiff;
+		frac1 += frac2;
+	} else {
+		a.parts.exp = exp1;
+		a.parts.fraction = (frac1 >> 6) & (~(FLOAT32_HIDDEN_BIT_MASK));
+		return a;
+	}
+	
+	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	/* rounding - if first bit after fraction is set then round up */
+	frac1 += (0x1 << 5);
+	
+	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) { 
+		/* rounding overflow */
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	if ((exp1 == FLOAT32_MAX_EXPONENT ) || (exp2 > exp1)) {
+		/* overflow - set infinity as result */
+		a.parts.exp = FLOAT32_MAX_EXPONENT;
+		a.parts.fraction = 0;
+		return a;
+	}
+	
+	a.parts.exp = exp1;
+	
+	/* Clear hidden bit and shift */
+	a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
+	return a;
+}
+
+/** Add two double-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ * @return Result of addition.
+ */
+float64 add_float64(float64 a, float64 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2;
+	uint64_t frac1, frac2;
+	
+	expdiff = ((int) a.parts.exp) - b.parts.exp;
+	if (expdiff < 0) {
+		if (is_float64_nan(b)) {
+			/* TODO: fix SigNaN */
+			if (is_float64_signan(b)) {
+			}
+
+			return b;
+		}
+		
+		/* b is infinity and a not */
+		if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
+			return b;
+		}
+		
+		frac1 = b.parts.fraction;
+		exp1 = b.parts.exp;
+		frac2 = a.parts.fraction;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if (is_float64_nan(a)) {
+			/* TODO: fix SigNaN */
+			if (is_float64_signan(a) || is_float64_signan(b)) {
+			}
+			return a;
+		}
+		
+		/* a is infinity and b not */
+		if (a.parts.exp == FLOAT64_MAX_EXPONENT) { 
+			return a;
+		}
+		
+		frac1 = a.parts.fraction;
+		exp1 = a.parts.exp;
+		frac2 = b.parts.fraction;
+		exp2 = b.parts.exp;
+	}
+	
+	if (exp1 == 0) {
+		/* both are denormalized */
+		frac1 += frac2;
+		if (frac1 & FLOAT64_HIDDEN_BIT_MASK) { 
+			/* result is not denormalized */
+			a.parts.exp = 1;
+		}
+		a.parts.fraction = frac1;
+		return a;
+	}
+	
+	/* add hidden bit - frac1 is sure not denormalized */
+	frac1 |= FLOAT64_HIDDEN_BIT_MASK;
+
+	/* second operand ... */
+	if (exp2 == 0) {
+		/* ... is denormalized */
+		--expdiff;	
+	} else {
+		/* is not denormalized */
+		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
+	}
+	
+	/* create some space for rounding */
+	frac1 <<= 6;
+	frac2 <<= 6;
+	
+	if (expdiff < (FLOAT64_FRACTION_SIZE + 2)) {
+		frac2 >>= expdiff;
+		frac1 += frac2;
+	} else {
+		a.parts.exp = exp1;
+		a.parts.fraction = (frac1 >> 6) & (~(FLOAT64_HIDDEN_BIT_MASK));
+		return a;
+	}
+	
+	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	/* rounding - if first bit after fraction is set then round up */
+	frac1 += (0x1 << 5); 
+	
+	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) { 
+		/* rounding overflow */
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	if ((exp1 == FLOAT64_MAX_EXPONENT ) || (exp2 > exp1)) {
+		/* overflow - set infinity as result */
+		a.parts.exp = FLOAT64_MAX_EXPONENT;
+		a.parts.fraction = 0;
+		return a;
+	}
+	
+	a.parts.exp = exp1;
+	/* Clear hidden bit and shift */
+	a.parts.fraction = ((frac1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
+	return a;
+}
+
+/** Add two quadruple-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ * @return Result of addition.
+ */
+float128 add_float128(float128 a, float128 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2;
+	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
+
+	expdiff = ((int) a.parts.exp) - b.parts.exp;
+	if (expdiff < 0) {
+		if (is_float128_nan(b)) {
+			/* TODO: fix SigNaN */
+			if (is_float128_signan(b)) {
+			}
+
+			return b;
+		}
+
+		/* b is infinity and a not */
+		if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
+			return b;
+		}
+
+		frac1_hi = b.parts.frac_hi;
+		frac1_lo = b.parts.frac_lo;
+		exp1 = b.parts.exp;
+		frac2_hi = a.parts.frac_hi;
+		frac2_lo = a.parts.frac_lo;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if (is_float128_nan(a)) {
+			/* TODO: fix SigNaN */
+			if (is_float128_signan(a) || is_float128_signan(b)) {
+			}
+			return a;
+		}
+
+		/* a is infinity and b not */
+		if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
+			return a;
+		}
+
+		frac1_hi = a.parts.frac_hi;
+		frac1_lo = a.parts.frac_lo;
+		exp1 = a.parts.exp;
+		frac2_hi = b.parts.frac_hi;
+		frac2_lo = b.parts.frac_lo;
+		exp2 = b.parts.exp;
+	}
+
+	if (exp1 == 0) {
+		/* both are denormalized */
+		add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
+
+		and128(frac1_hi, frac1_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			/* result is not denormalized */
+			a.parts.exp = 1;
+		}
+
+		a.parts.frac_hi = frac1_hi;
+		a.parts.frac_lo = frac1_lo;
+		return a;
+	}
+
+	/* add hidden bit - frac1 is sure not denormalized */
+	or128(frac1_hi, frac1_lo,
+	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &frac1_hi, &frac1_lo);
+
+	/* second operand ... */
+	if (exp2 == 0) {
+		/* ... is denormalized */
+		--expdiff;
+	} else {
+		/* is not denormalized */
+		or128(frac2_hi, frac2_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &frac2_hi, &frac2_lo);
+	}
+
+	/* create some space for rounding */
+	lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
+	lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
+
+	if (expdiff < (FLOAT128_FRACTION_SIZE + 2)) {
+		rshift128(frac2_hi, frac2_lo, expdiff, &frac2_hi, &frac2_lo);
+		add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
+	} else {
+		a.parts.exp = exp1;
+
+		rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
+		not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+
+		a.parts.frac_hi = tmp_hi;
+		a.parts.frac_lo = tmp_lo;
+		return a;
+	}
+
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
+	    &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+		++exp1;
+		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
+	}
+
+	/* rounding - if first bit after fraction is set then round up */
+	add128(frac1_hi, frac1_lo, 0x0ll, 0x1ll << 5, &frac1_hi, &frac1_lo);
+
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
+	   &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+		/* rounding overflow */
+		++exp1;
+		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
+	}
+
+	if ((exp1 == FLOAT128_MAX_EXPONENT ) || (exp2 > exp1)) {
+		/* overflow - set infinity as result */
+		a.parts.exp = FLOAT64_MAX_EXPONENT;
+		a.parts.frac_hi = 0;
+		a.parts.frac_lo = 0;
+		return a;
+	}
+
+	a.parts.exp = exp1;
+	
+	/* Clear hidden bit and shift */
+	rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
+	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+
+	a.parts.frac_hi = tmp_hi;
+	a.parts.frac_lo = tmp_lo;
+
+	return a;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/add.h
===================================================================
--- uspace/lib/softfloat/add.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/add.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,47 @@
+/*
+ * 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 Addition functions.
+ */
+
+#ifndef __ADD_H__
+#define __ADD_H__
+
+extern float32 add_float32(float32, float32);
+extern float64 add_float64(float64, float64);
+extern float96 add_float96(float96, float96);
+extern float128 add_float128(float128, float128);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/common.c
===================================================================
--- uspace/lib/softfloat/common.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/common.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,690 @@
+/*
+ * 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 Common helper operations.
+ */
+
+#include "sftypes.h"
+#include "common.h"
+
+/* Table for fast leading zeroes counting. */
+char zeroTable[256] = {
+	8, 7, 7, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, \
+	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
+	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/**
+ * Take fraction shifted by 10 bits to the left, round it, normalize it
+ * and detect exceptions
+ * 
+ * @param cexp Exponent with bias.
+ * @param cfrac Fraction shifted 10 bits to the left with added hidden bit.
+ * @param sign Resulting sign.
+ * @return Finished double-precision float.
+ */
+float64 finish_float64(int32_t cexp, uint64_t cfrac, char sign)
+{
+	float64 result;
+
+	result.parts.sign = sign;
+
+	/* find first nonzero digit and shift result and detect possibly underflow */
+	while ((cexp > 0) && (cfrac) &&
+	    (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1))))) {
+		cexp--;
+		cfrac <<= 1;
+		/* TODO: fix underflow */
+	}
+	
+	if ((cexp < 0) || (cexp == 0 &&
+	    (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
+		/* FIXME: underflow */
+		result.parts.exp = 0;
+		if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		while (cexp < 0) {
+			cexp++;
+			cfrac >>= 1;
+		}
+	
+		cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3)); 
+		
+		if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))) {
+			result.parts.fraction =
+			    ((cfrac >> (64 - FLOAT64_FRACTION_SIZE - 2)) & (~FLOAT64_HIDDEN_BIT_MASK));
+			return result;
+		}	
+	} else {
+		cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3)); 
+	}
+	
+	++cexp;
+
+	if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1))) {
+		++cexp;
+		cfrac >>= 1;
+	}
+
+	/* check overflow */
+	if (cexp >= FLOAT64_MAX_EXPONENT) {
+		/* FIXME: overflow, return infinity */
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		result.parts.fraction = 0;
+		return result;
+	}
+
+	result.parts.exp = (uint32_t) cexp;
+	
+	result.parts.fraction = 
+	    ((cfrac >> (64 - FLOAT64_FRACTION_SIZE - 2)) & (~FLOAT64_HIDDEN_BIT_MASK));
+	
+	return result;	
+}
+
+/**
+ * Take fraction, round it, normalize it and detect exceptions
+ * 
+ * @param cexp Exponent with bias.
+ * @param cfrac_hi High part of the fraction shifted 14 bits to the left
+ *     with added hidden bit.
+ * @param cfrac_lo Low part of the fraction shifted 14 bits to the left
+ *     with added hidden bit.
+ * @param sign Resulting sign.
+ * @param shift_out Bits right-shifted out from fraction by the caller.
+ * @return Finished quadruple-precision float.
+ */
+float128 finish_float128(int32_t cexp, uint64_t cfrac_hi, uint64_t cfrac_lo, 
+    char sign, uint64_t shift_out)
+{
+	float128 result;
+	uint64_t tmp_hi, tmp_lo;
+
+	result.parts.sign = sign;
+
+	/* find first nonzero digit and shift result and detect possibly underflow */
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    1, &tmp_hi, &tmp_lo);
+	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	while ((cexp > 0) && (lt128(0x0ll, 0x0ll, cfrac_hi, cfrac_lo)) &&
+	    (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo))) {
+		cexp--;
+		lshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
+		/* TODO: fix underflow */
+
+		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    1, &tmp_hi, &tmp_lo);
+		and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	}
+
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    1, &tmp_hi, &tmp_lo);
+	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if ((cexp < 0) || (cexp == 0 &&
+	    (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)))) {
+		/* FIXME: underflow */
+		result.parts.exp = 0;
+		if ((cexp + FLOAT128_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
+			result.parts.frac_hi = 0x0ll;
+			result.parts.frac_lo = 0x0ll;
+			return result;
+		}
+
+		while (cexp < 0) {
+			cexp++;
+			rshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
+		}
+
+		if (shift_out & (0x1ull < 64)) {
+			add128(cfrac_hi, cfrac_lo, 0x0ll, 0x1ll, &cfrac_hi, &cfrac_lo);
+		}
+
+		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    1, &tmp_hi, &tmp_lo);
+		and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+		if (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+			    &tmp_hi, &tmp_lo);
+			and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+			result.parts.frac_hi = tmp_hi;
+			result.parts.frac_lo = tmp_lo;
+			return result;
+		}
+	} else {
+		if (shift_out & (0x1ull < 64)) {
+			add128(cfrac_hi, cfrac_lo, 0x0ll, 0x1ll, &cfrac_hi, &cfrac_lo);
+		}
+	}
+
+	++cexp;
+
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    1, &tmp_hi, &tmp_lo);
+	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+		++cexp;
+		rshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
+	}
+
+	/* check overflow */
+	if (cexp >= FLOAT128_MAX_EXPONENT) {
+		/* FIXME: overflow, return infinity */
+		result.parts.exp = FLOAT128_MAX_EXPONENT;
+		result.parts.frac_hi = 0x0ll;
+		result.parts.frac_lo = 0x0ll;
+		return result;
+	}
+
+	result.parts.exp = (uint32_t) cexp;
+
+	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &tmp_hi, &tmp_lo);
+	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	result.parts.frac_hi = tmp_hi;
+	result.parts.frac_lo = tmp_lo;
+
+	return result;	
+}
+
+/**
+ * Counts leading zeroes in byte.
+ *
+ * @param i Byte for which to count leading zeroes.
+ * @return Number of detected leading zeroes.
+ */
+int count_zeroes8(uint8_t i)
+{
+	return zeroTable[i];
+}
+
+/** 
+ * Counts leading zeroes in 32bit unsigned integer.
+ *
+ * @param i Integer for which to count leading zeroes.
+ * @return Number of detected leading zeroes.
+ */
+int count_zeroes32(uint32_t i)
+{
+	int j;
+	for (j = 0; j < 32; j += 8) {
+		if (i & (0xFF << (24 - j))) {
+			return (j + count_zeroes8(i >> (24 - j)));
+		}
+	}
+
+	return 32;
+}
+
+/**
+ * Counts leading zeroes in 64bit unsigned integer.
+ *
+ * @param i Integer for which to count leading zeroes.
+ * @return Number of detected leading zeroes.
+ */
+int count_zeroes64(uint64_t i)
+{
+	int j;
+	for (j = 0; j < 64; j += 8) {
+		if (i & (0xFFll << (56 - j))) {
+			return (j + count_zeroes8(i >> (56 - j)));
+		}
+	}
+
+	return 64;
+}
+
+/**
+ * Round and normalize number expressed by exponent and fraction with
+ * first bit (equal to hidden bit) at 30th bit.
+ *
+ * @param exp Exponent part.
+ * @param fraction Fraction with hidden bit shifted to 30th bit.
+ */
+void round_float32(int32_t *exp, uint32_t *fraction)
+{
+	/* rounding - if first bit after fraction is set then round up */
+	(*fraction) += (0x1 << (32 - FLOAT32_FRACTION_SIZE - 3));
+	
+	if ((*fraction) & 
+	    (FLOAT32_HIDDEN_BIT_MASK << (32 - FLOAT32_FRACTION_SIZE - 1))) {
+		/* rounding overflow */
+		++(*exp);
+		(*fraction) >>= 1;
+	}
+	
+	if (((*exp) >= FLOAT32_MAX_EXPONENT) || ((*exp) < 0)) {
+		/* overflow - set infinity as result */
+		(*exp) = FLOAT32_MAX_EXPONENT;
+		(*fraction) = 0;
+	}
+}
+
+/**
+ * Round and normalize number expressed by exponent and fraction with
+ * first bit (equal to hidden bit) at 62nd bit.
+ *
+ * @param exp Exponent part.
+ * @param fraction Fraction with hidden bit shifted to 62nd bit.
+ */
+void round_float64(int32_t *exp, uint64_t *fraction)
+{
+	/* rounding - if first bit after fraction is set then round up */
+	(*fraction) += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
+	
+	if ((*fraction) & 
+	    (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 3))) {
+		/* rounding overflow */
+		++(*exp);
+		(*fraction) >>= 1;
+	}
+	
+	if (((*exp) >= FLOAT64_MAX_EXPONENT) || ((*exp) < 0)) {
+		/* overflow - set infinity as result */
+		(*exp) = FLOAT64_MAX_EXPONENT;
+		(*fraction) = 0;
+	}
+}
+
+/**
+ * Round and normalize number expressed by exponent and fraction with
+ * first bit (equal to hidden bit) at 126th bit.
+ *
+ * @param exp Exponent part.
+ * @param frac_hi High part of fraction part with hidden bit shifted to 126th bit.
+ * @param frac_lo Low part of fraction part with hidden bit shifted to 126th bit.
+ */
+void round_float128(int32_t *exp, uint64_t *frac_hi, uint64_t *frac_lo)
+{
+	uint64_t tmp_hi, tmp_lo;
+
+	/* rounding - if first bit after fraction is set then round up */
+	lshift128(0x0ll, 0x1ll, (128 - FLOAT128_FRACTION_SIZE - 3), &tmp_hi, &tmp_lo);
+	add128(*frac_hi, *frac_lo, tmp_hi, tmp_lo, frac_hi, frac_lo);
+
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    (128 - FLOAT128_FRACTION_SIZE - 3), &tmp_hi, &tmp_lo);
+	and128(*frac_hi, *frac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+		/* rounding overflow */
+		++(*exp);
+		rshift128(*frac_hi, *frac_lo, 1, frac_hi, frac_lo);
+	}
+
+	if (((*exp) >= FLOAT128_MAX_EXPONENT) || ((*exp) < 0)) {
+		/* overflow - set infinity as result */
+		(*exp) = FLOAT128_MAX_EXPONENT;
+		(*frac_hi) = 0;
+		(*frac_lo) = 0;
+	}
+}
+
+/**
+ * Logical shift left on the 128-bit operand.
+ *
+ * @param a_hi High part of the input operand.
+ * @param a_lo Low part of the input operand.
+ * @param shift Number of bits by witch to shift.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void lshift128(
+    uint64_t a_hi, uint64_t a_lo, int shift,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	if (shift <= 0) {
+		/* do nothing */
+	} else if (shift >= 128) {
+		a_hi = 0;
+		a_lo = 0;
+	} else if (shift >= 64) {
+		a_hi = a_lo << (shift - 64);
+		a_lo = 0;
+	} else {
+		a_hi <<= shift;
+		a_hi |= a_lo >> (64 - shift);
+		a_lo <<= shift;
+	}
+
+	*r_hi = a_hi;
+	*r_lo = a_lo;
+}
+
+/**
+ * Logical shift right on the 128-bit operand.
+ *
+ * @param a_hi High part of the input operand.
+ * @param a_lo Low part of the input operand.
+ * @param shift Number of bits by witch to shift.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void rshift128(
+    uint64_t a_hi, uint64_t a_lo, int shift,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	if (shift <= 0) {
+		/* do nothing */
+	} else 	if (shift >= 128) {
+		a_hi = 0;
+		a_lo = 0;
+	} else if (shift >= 64) {
+		a_lo = a_hi >> (shift - 64);
+		a_hi = 0;
+	} else {
+		a_lo >>= shift;
+		a_lo |= a_hi << (64 - shift);
+		a_hi >>= shift;
+	}
+
+	*r_hi = a_hi;
+	*r_lo = a_lo;
+}
+
+/**
+ * Bitwise AND on 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void and128(
+    uint64_t a_hi, uint64_t a_lo,
+    uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	*r_hi = a_hi & b_hi;
+	*r_lo = a_lo & b_lo;
+}
+
+/**
+ * Bitwise inclusive OR on 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void or128(
+    uint64_t a_hi, uint64_t a_lo,
+    uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	*r_hi = a_hi | b_hi;
+	*r_lo = a_lo | b_lo;
+}
+
+/**
+ * Bitwise exclusive OR on 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void xor128(
+    uint64_t a_hi, uint64_t a_lo,
+    uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	*r_hi = a_hi ^ b_hi;
+	*r_lo = a_lo ^ b_lo;
+}
+
+/**
+ * Bitwise NOT on the 128-bit operand.
+ *
+ * @param a_hi High part of the input operand.
+ * @param a_lo Low part of the input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void not128(
+    uint64_t a_hi, uint64_t a_lo,
+	uint64_t *r_hi, uint64_t *r_lo)
+{
+	*r_hi = ~a_hi;
+	*r_lo = ~a_lo;
+}
+
+/**
+ * Equality comparison of 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @return 1 if operands are equal, 0 otherwise.
+ */
+int eq128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
+{
+	return (a_hi == b_hi) && (a_lo == b_lo);
+}
+
+/**
+ * Lower-or-equal comparison of 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @return 1 if a is lower or equal to b, 0 otherwise.
+ */
+int le128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
+{
+	return (a_hi < b_hi) || ((a_hi == b_hi) && (a_lo <= b_lo));
+}
+
+/**
+ * Lower-than comparison of 128-bit operands.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @return 1 if a is lower than b, 0 otherwise.
+ */
+int lt128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
+{
+	return (a_hi < b_hi) || ((a_hi == b_hi) && (a_lo < b_lo));
+}
+
+/**
+ * Addition of two 128-bit unsigned integers.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void add128(uint64_t a_hi, uint64_t a_lo,
+    uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	uint64_t low = a_lo + b_lo;
+	*r_lo = low;
+	/* detect overflow to add a carry */
+	*r_hi = a_hi + b_hi + (low < a_lo);
+}
+
+/**
+ * Substraction of two 128-bit unsigned integers.
+ *
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void sub128(uint64_t a_hi, uint64_t a_lo,
+    uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hi, uint64_t *r_lo)
+{
+	*r_lo = a_lo - b_lo;
+	/* detect underflow to substract a carry */
+	*r_hi = a_hi - b_hi - (a_lo < b_lo);
+}
+
+/**
+ * Multiplication of two 64-bit unsigned integers.
+ * 
+ * @param a First input operand.
+ * @param b Second input operand.
+ * @param r_hi Address to store high part of the result.
+ * @param r_lo Address to store low part of the result.
+ */
+void mul64(uint64_t a, uint64_t b, uint64_t *r_hi, uint64_t *r_lo)
+{
+	uint64_t low, high, middle1, middle2;
+	uint32_t alow, blow;
+
+	alow = a & 0xFFFFFFFF;
+	blow = b & 0xFFFFFFFF;
+
+	a >>= 32;
+	b >>= 32;
+
+	low = ((uint64_t) alow) * blow;
+	middle1 = a * blow;
+	middle2 = alow * b;
+	high = a * b;
+
+	middle1 += middle2;
+	high += (((uint64_t) (middle1 < middle2)) << 32) + (middle1 >> 32);
+	middle1 <<= 32;
+	low += middle1;
+	high += (low < middle1);
+	*r_lo = low;
+	*r_hi = high;
+}
+
+/**
+ * Multiplication of two 128-bit unsigned integers.
+ * 
+ * @param a_hi High part of the first input operand.
+ * @param a_lo Low part of the first input operand.
+ * @param b_hi High part of the second input operand.
+ * @param b_lo Low part of the second input operand.
+ * @param r_hihi Address to store first (highest) quarter of the result.
+ * @param r_hilo Address to store second quarter of the result.
+ * @param r_lohi Address to store third quarter of the result.
+ * @param r_lolo Address to store fourth (lowest) quarter of the result.
+ */
+void mul128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo,
+    uint64_t *r_hihi, uint64_t *r_hilo, uint64_t *r_lohi, uint64_t *r_lolo)
+{
+	uint64_t hihi, hilo, lohi, lolo;
+	uint64_t tmp1, tmp2;
+
+	mul64(a_lo, b_lo, &lohi, &lolo);
+	mul64(a_lo, b_hi, &hilo, &tmp2);
+	add128(hilo, tmp2, 0x0ll, lohi, &hilo, &lohi);
+	mul64(a_hi, b_hi, &hihi, &tmp1);
+	add128(hihi, tmp1, 0x0ll, hilo, &hihi, &hilo);
+	mul64(a_hi, b_lo, &tmp1, &tmp2);
+	add128(tmp1, tmp2, 0x0ll, lohi, &tmp1, &lohi);
+	add128(hihi, hilo, 0x0ll, tmp1, &hihi, &hilo);
+
+	*r_hihi = hihi;
+	*r_hilo = hilo;
+	*r_lohi = lohi;
+	*r_lolo = lolo;
+}
+
+/**
+ * Estimate the quotient of 128-bit unsigned divident and 64-bit unsigned
+ * divisor.
+ * 
+ * @param a_hi High part of the divident.
+ * @param a_lo Low part of the divident.
+ * @param b Divisor.
+ * @return Quotient approximation.
+ */
+uint64_t div128est(uint64_t a_hi, uint64_t a_lo, uint64_t b)
+{
+	uint64_t b_hi, b_lo;
+	uint64_t rem_hi, rem_lo;
+	uint64_t tmp_hi, tmp_lo;
+	uint64_t result;
+
+	if (b <= a_hi) {
+		return 0xFFFFFFFFFFFFFFFFull;
+	}
+
+	b_hi = b >> 32;
+	result = ((b_hi << 32) <= a_hi) ? (0xFFFFFFFFull << 32) : (a_hi / b_hi) << 32;
+	mul64(b, result, &tmp_hi, &tmp_lo);
+	sub128(a_hi, a_lo, tmp_hi, tmp_lo, &rem_hi, &rem_lo);
+	
+	while ((int64_t) rem_hi < 0) {
+		result -= 0x1ll << 32;
+		b_lo = b << 32;
+		add128(rem_hi, rem_lo, b_hi, b_lo, &rem_hi, &rem_lo);
+	}
+
+	rem_hi = (rem_hi << 32) | (rem_lo >> 32);
+	if ((b_hi << 32) <= rem_hi) {
+		result |= 0xFFFFFFFF;
+	} else {
+		result |= rem_hi / b_hi;
+	}
+
+	return result;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/common.h
===================================================================
--- uspace/lib/softfloat/common.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/common.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,76 @@
+/*
+ * 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 Common helper operations.
+ */
+
+#ifndef __COMMON_H__
+#define __COMMON_H__
+
+#include "sftypes.h"
+
+extern float64 finish_float64(int32_t, uint64_t, char);
+extern float128 finish_float128(int32_t, uint64_t, uint64_t, char, uint64_t);
+
+extern int count_zeroes8(uint8_t);
+extern int count_zeroes32(uint32_t);
+extern int count_zeroes64(uint64_t);
+
+extern void round_float32(int32_t *, uint32_t *);
+extern void round_float64(int32_t *, uint64_t *);
+extern void round_float128(int32_t *, uint64_t *, uint64_t *);
+
+extern void lshift128(uint64_t, uint64_t, int, uint64_t *, uint64_t *);
+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 not128(uint64_t, uint64_t, uint64_t *, uint64_t *);
+
+extern int eq128(uint64_t, uint64_t, uint64_t, uint64_t);
+extern int le128(uint64_t, uint64_t, uint64_t, uint64_t);
+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 mul64(uint64_t, uint64_t, uint64_t *, uint64_t *);
+extern void mul128(uint64_t, uint64_t, uint64_t, uint64_t,
+    uint64_t *, uint64_t *, uint64_t *, uint64_t *);
+
+extern uint64_t div128est(uint64_t, uint64_t, uint64_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/comparison.c
===================================================================
--- uspace/lib/softfloat/comparison.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/comparison.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,442 @@
+/*
+ * 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 Comparison functions.
+ */
+
+#include "sftypes.h"
+#include "comparison.h"
+#include "common.h"
+
+/**
+ * Determines whether the given float represents NaN (either signalling NaN or
+ * quiet NaN).
+ *
+ * @param f Single-precision float.
+ * @return 1 if float is NaN, 0 otherwise.
+ */
+int is_float32_nan(float32 f)
+{
+	/* NaN : exp = 0xff and nonzero fraction */
+	return ((f.parts.exp == 0xFF) && (f.parts.fraction));
+}
+
+/**
+ * Determines whether the given float represents NaN (either signalling NaN or
+ * quiet NaN).
+ *
+ * @param d Double-precision float.
+ * @return 1 if float is NaN, 0 otherwise.
+ */
+int is_float64_nan(float64 d)
+{
+	/* NaN : exp = 0x7ff and nonzero fraction */
+	return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
+}
+
+/**
+ * Determines whether the given float represents NaN (either signalling NaN or
+ * quiet NaN).
+ *
+ * @param ld Quadruple-precision float.
+ * @return 1 if float is NaN, 0 otherwise.
+ */
+int is_float128_nan(float128 ld)
+{
+	/* NaN : exp = 0x7fff and nonzero fraction */
+	return ((ld.parts.exp == 0x7FF) &&
+	    !eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
+}
+
+/**
+ * Determines whether the given float represents signalling NaN.
+ *
+ * @param f Single-precision float.
+ * @return 1 if float is signalling NaN, 0 otherwise.
+ */
+int is_float32_signan(float32 f)
+{
+	/* SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary),
+	 * where at least one x is nonzero */
+	return ((f.parts.exp == 0xFF) &&
+	    (f.parts.fraction < 0x400000) && (f.parts.fraction));
+}
+
+/**
+ * Determines whether the given float represents signalling NaN.
+ *
+ * @param d Double-precision float.
+ * @return 1 if float is signalling NaN, 0 otherwise.
+ */
+int is_float64_signan(float64 d)
+{
+	/* SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),
+	 * where at least one x is nonzero */
+	return ((d.parts.exp == 0x7FF) &&
+	    (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
+}
+
+/**
+ * Determines whether the given float represents signalling NaN.
+ *
+ * @param ld Quadruple-precision float.
+ * @return 1 if float is signalling NaN, 0 otherwise.
+ */
+int is_float128_signan(float128 ld)
+{
+	/* SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),
+	 * where at least one x is nonzero */
+	return ((ld.parts.exp == 0x7FFF) &&
+	    (ld.parts.frac_hi || ld.parts.frac_lo) &&
+	    lt128(ld.parts.frac_hi, ld.parts.frac_lo, 0x800000000000ll, 0x0ll));
+
+}
+
+/**
+ * Determines whether the given float represents positive or negative infinity.
+ *
+ * @param f Single-precision float.
+ * @return 1 if float is infinite, 0 otherwise.
+ */
+int is_float32_infinity(float32 f)
+{
+	/* NaN : exp = 0x7ff and zero fraction */
+	return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
+}
+
+/**
+ * Determines whether the given float represents positive or negative infinity.
+ *
+ * @param d Double-precision float.
+ * @return 1 if float is infinite, 0 otherwise.
+ */
+int is_float64_infinity(float64 d)
+{
+	/* NaN : exp = 0x7ff and zero fraction */
+	return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
+}
+
+/**
+ * Determines whether the given float represents positive or negative infinity.
+ *
+ * @param ld Quadruple-precision float.
+ * @return 1 if float is infinite, 0 otherwise.
+ */
+int is_float128_infinity(float128 ld)
+{
+	/* NaN : exp = 0x7fff and zero fraction */
+	return ((ld.parts.exp == 0x7FFF) &&
+	    eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
+}
+
+/**
+ * Determines whether the given float represents positive or negative zero.
+ *
+ * @param f Single-precision float.
+ * @return 1 if float is zero, 0 otherwise.
+ */
+int is_float32_zero(float32 f)
+{
+	return (((f.bin) & 0x7FFFFFFF) == 0);
+}
+
+/**
+ * Determines whether the given float represents positive or negative zero.
+ *
+ * @param d Double-precision float.
+ * @return 1 if float is zero, 0 otherwise.
+ */
+int is_float64_zero(float64 d)
+{
+	return (((d.bin) & 0x7FFFFFFFFFFFFFFFll) == 0);
+}
+
+/**
+ * Determines whether the given float represents positive or negative zero.
+ *
+ * @param ld Quadruple-precision float.
+ * @return 1 if float is zero, 0 otherwise.
+ */
+int is_float128_zero(float128 ld)
+{
+	uint64_t tmp_hi;
+	uint64_t tmp_lo;
+	
+	and128(ld.bin.hi, ld.bin.lo,
+	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
+	
+	return eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
+}
+
+/**
+ * Determine whether two floats are equal. NaNs are not recognized.
+ *
+ * @a First single-precision operand.
+ * @b Second single-precision operand.
+ * @return 1 if both floats are equal, 0 otherwise.
+ */
+int is_float32_eq(float32 a, float32 b)
+{
+	/* a equals to b or both are zeros (with any sign) */
+	return ((a.bin == b.bin) ||
+	    (((a.bin | b.bin) & 0x7FFFFFFF) == 0));
+}
+
+/**
+ * Determine whether two floats are equal. NaNs are not recognized.
+ *
+ * @a First double-precision operand.
+ * @b Second double-precision operand.
+ * @return 1 if both floats are equal, 0 otherwise.
+ */
+int is_float64_eq(float64 a, float64 b)
+{
+	/* a equals to b or both are zeros (with any sign) */
+	return ((a.bin == b.bin) ||
+	    (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0));
+}
+
+/**
+ * Determine whether two floats are equal. NaNs are not recognized.
+ *
+ * @a First quadruple-precision operand.
+ * @b Second quadruple-precision operand.
+ * @return 1 if both floats are equal, 0 otherwise.
+ */
+int is_float128_eq(float128 a, float128 b)
+{
+	uint64_t tmp_hi;
+	uint64_t tmp_lo;
+	
+	/* both are zeros (with any sign) */
+	or128(a.bin.hi, a.bin.lo,
+	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
+	and128(tmp_hi, tmp_lo,
+	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
+	int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
+	
+	/* a equals to b */
+	int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
+	
+	return are_equal || both_zero;
+}
+
+/**
+ * Lower-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First single-precision operand.
+ * @b Second single-precision operand.
+ * @return 1 if a is lower than b, 0 otherwise.
+ */
+int is_float32_lt(float32 a, float32 b) 
+{
+	if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
+		/* +- zeroes */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, smaller is that with greater binary value */
+		return (a.bin > b.bin);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return (a.bin < b.bin);
+}
+
+/**
+ * Lower-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First double-precision operand.
+ * @b Second double-precision operand.
+ * @return 1 if a is lower than b, 0 otherwise.
+ */
+int is_float64_lt(float64 a, float64 b)
+{
+	if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
+		/* +- zeroes */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, smaller is that with greater binary value */
+		return (a.bin > b.bin);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return (a.bin < b.bin);
+}
+
+/**
+ * Lower-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First quadruple-precision operand.
+ * @b Second quadruple-precision operand.
+ * @return 1 if a is lower than b, 0 otherwise.
+ */
+int is_float128_lt(float128 a, float128 b)
+{
+	uint64_t tmp_hi;
+	uint64_t tmp_lo;
+	
+	or128(a.bin.hi, a.bin.lo,
+	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
+	and128(tmp_hi, tmp_lo,
+	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
+	if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
+		/* +- zeroes */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, smaller is that with greater binary value */
+		return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
+}
+
+/**
+ * Greater-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First single-precision operand.
+ * @b Second single-precision operand.
+ * @return 1 if a is greater than b, 0 otherwise.
+ */
+int is_float32_gt(float32 a, float32 b) 
+{
+	if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
+		/* zeroes are equal with any sign */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, greater is that with smaller binary value */
+		return (a.bin < b.bin);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return (a.bin > b.bin);
+}
+
+/**
+ * Greater-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First double-precision operand.
+ * @b Second double-precision operand.
+ * @return 1 if a is greater than b, 0 otherwise.
+ */
+int is_float64_gt(float64 a, float64 b)
+{
+	if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
+		/* zeroes are equal with any sign */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, greater is that with smaller binary value */
+		return (a.bin < b.bin);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return (a.bin > b.bin);
+}
+
+/**
+ * Greater-than comparison between two floats. NaNs are not recognized.
+ *
+ * @a First quadruple-precision operand.
+ * @b Second quadruple-precision operand.
+ * @return 1 if a is greater than b, 0 otherwise.
+ */
+int is_float128_gt(float128 a, float128 b)
+{
+	uint64_t tmp_hi;
+	uint64_t tmp_lo;
+	
+	or128(a.bin.hi, a.bin.lo,
+	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
+	and128(tmp_hi, tmp_lo,
+	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
+	if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
+		/* zeroes are equal with any sign */
+		return 0;
+	}
+	
+	if ((a.parts.sign) && (b.parts.sign)) {
+		/* if both are negative, greater is that with smaller binary value */
+		return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
+	}
+	
+	/*
+	 * lets negate signs - now will be positive numbers always
+	 * bigger than negative (first bit will be set for unsigned
+	 * integer comparison)
+	 */
+	a.parts.sign = !a.parts.sign;
+	b.parts.sign = !b.parts.sign;
+	return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/comparison.h
===================================================================
--- uspace/lib/softfloat/comparison.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/comparison.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,82 @@
+/*
+ * 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 Comparison functions.
+ */
+
+#ifndef __COMPARISON_H__
+#define __COMPARISON_H__
+
+extern int is_float32_nan(float32);
+extern int is_float32_signan(float32);
+
+extern int is_float32_infinity(float32);
+extern int is_float32_zero(float32);
+
+extern int is_float32_eq(float32, float32);
+extern int is_float32_lt(float32, float32);
+extern int is_float32_gt(float32, float32);
+
+extern int is_float64_nan(float64);
+extern int is_float64_signan(float64);
+
+extern int is_float64_infinity(float64);
+extern int is_float64_zero(float64);
+
+extern int is_float64_eq(float64, float64);
+extern int is_float64_lt(float64, float64);
+extern int is_float64_gt(float64, float64);
+
+extern int is_float96_nan(float96);
+extern int is_float96_signan(float96);
+
+extern int is_float96_infinity(float96);
+extern int is_float96_zero(float96);
+
+extern int is_float96_eq(float96, float96);
+extern int is_float96_lt(float96, float96);
+extern int is_float96_gt(float96, float96);
+
+extern int is_float128_nan(float128);
+extern int is_float128_signan(float128);
+
+extern int is_float128_infinity(float128);
+extern int is_float128_zero(float128);
+
+extern int is_float128_eq(float128, float128);
+extern int is_float128_lt(float128, float128);
+extern int is_float128_gt(float128, float128);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/conversion.c
===================================================================
--- uspace/lib/softfloat/conversion.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/conversion.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,1041 @@
+/*
+ * 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 Conversion of precision and conversion between integers and floats.
+ */
+
+#include "sftypes.h"
+#include "conversion.h"
+#include "comparison.h"
+#include "common.h"
+
+float64 float32_to_float64(float32 a)
+{
+	float64 result;
+	uint64_t frac;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.fraction = a.parts.fraction;
+	result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
+	
+	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (result.parts.fraction == 0) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+			
+		frac = result.parts.fraction;
+		
+		while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
+			frac <<= 1;
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.fraction = frac;
+	}
+	
+	return result;
+}
+
+float128 float32_to_float128(float32 a)
+{
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	uint64_t tmp_hi, tmp_lo;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = a.parts.fraction;
+	lshift128(result.parts.frac_hi, result.parts.frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE),
+	    &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	
+	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
+		result.parts.exp = FLOAT128_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (eq128(result.parts.frac_hi,
+		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+		
+		frac_hi = result.parts.frac_hi;
+		frac_lo = result.parts.frac_lo;
+		
+		and128(frac_hi, frac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.frac_hi = frac_hi;
+		result.parts.frac_lo = frac_lo;
+	}
+	
+	return result;
+}
+
+float128 float64_to_float128(float64 a)
+{
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	uint64_t tmp_hi, tmp_lo;
+	
+	result.parts.sign = a.parts.sign;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = a.parts.fraction;
+	lshift128(result.parts.frac_hi, result.parts.frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE),
+	    &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	
+	if ((is_float64_infinity(a)) || (is_float64_nan(a))) {
+		result.parts.exp = FLOAT128_MAX_EXPONENT;
+		// TODO; check if its correct for SigNaNs
+		return result;
+	}
+	
+	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
+	if (a.parts.exp == 0) {
+		/* normalize denormalized numbers */
+		
+		if (eq128(result.parts.frac_hi,
+		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
+			result.parts.exp = 0;
+			return result;
+		}
+		
+		frac_hi = result.parts.frac_hi;
+		frac_lo = result.parts.frac_lo;
+		
+		and128(frac_hi, frac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hi, &tmp_lo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+			--result.parts.exp;
+		}
+		
+		++result.parts.exp;
+		result.parts.frac_hi = frac_hi;
+		result.parts.frac_lo = frac_lo;
+	}
+	
+	return result;
+}
+
+float32 float64_to_float32(float64 a)
+{
+	float32 result;
+	int32_t exp;
+	uint64_t frac;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float64_nan(a)) {
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		
+		if (is_float64_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float64_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;	
+		if (exp > FLOAT32_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac = a.parts.fraction; 
+		frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
+		
+		frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
+		
+		while (exp > 0) {
+			--exp;
+			frac >>= 1;
+		}
+		result.parts.fraction = frac;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	result.parts.fraction =
+	    a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
+	return result;
+}
+
+float32 float128_to_float32(float128 a)
+{
+	float32 result;
+	int32_t exp;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float128_nan(a)) {
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		
+		if (is_float128_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float128_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;
+		if (exp > FLOAT32_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac_hi = a.parts.frac_hi;
+		frac_lo = a.parts.frac_lo;
+		
+		/* denormalize and set hidden bit */
+		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+		
+		rshift128(frac_hi, frac_lo,
+		    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
+		    &frac_hi, &frac_lo);
+		
+		while (exp > 0) {
+			--exp;
+			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+		}
+		result.parts.fraction = frac_lo;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	rshift128(frac_hi, frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
+	    &frac_hi, &frac_lo);
+	result.parts.fraction = frac_lo;
+	return result;
+}
+
+float64 float128_to_float64(float128 a)
+{
+	float64 result;
+	int32_t exp;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = a.parts.sign;
+	
+	if (is_float128_nan(a)) {
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		
+		if (is_float128_signan(a)) {
+			/* set first bit of fraction nonzero */
+			result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
+			return result;
+		}
+		
+		/* fraction nonzero but its first bit is zero */
+		result.parts.fraction = 0x1;
+		return result;
+	}
+	
+	if (is_float128_infinity(a)) {
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		return result;
+	}
+	
+	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
+	
+	if (exp >= FLOAT64_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		result.parts.fraction = 0;
+		result.parts.exp = FLOAT64_MAX_EXPONENT;
+		return result;
+	} else if (exp <= 0) {
+		/* underflow or denormalized */
+		
+		result.parts.exp = 0;
+		
+		exp *= -1;
+		if (exp > FLOAT64_FRACTION_SIZE) {
+			/* FIXME: underflow */
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* denormalized */
+		
+		frac_hi = a.parts.frac_hi;
+		frac_lo = a.parts.frac_lo;
+		
+		/* denormalize and set hidden bit */
+		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+		
+		rshift128(frac_hi, frac_lo,
+		    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
+		    &frac_hi, &frac_lo);
+		
+		while (exp > 0) {
+			--exp;
+			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
+		}
+		result.parts.fraction = frac_lo;
+		
+		return result;
+	}
+	
+	result.parts.exp = exp;
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	rshift128(frac_hi, frac_lo,
+	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
+	    &frac_hi, &frac_lo);
+	result.parts.fraction = frac_lo;
+	return result;
+}
+
+/** Helper procedure for converting float32 to uint32.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint32_t _float32_to_uint32_helper(float32 a)
+{
+	uint32_t frac;
+	
+	if (a.parts.exp < FLOAT32_BIAS) {
+		/* TODO: rounding */
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT32_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 32 - FLOAT32_FRACTION_SIZE - 1; 
+	
+	frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float32_to_uint32(float32 a)
+{
+	if (is_float32_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return _float32_to_uint32_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float32_to_int32(float32 a)
+{
+	if (is_float32_nan(a))
+		return INT32_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return _float32_to_uint32_helper(a);
+}
+
+/** Helper procedure for converting float32 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float32_to_uint64_helper(float32 a)
+{
+	uint64_t frac;
+	
+	if (a.parts.exp < FLOAT32_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT32_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
+	
+	frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float32_to_uint64(float32 a)
+{
+	if (is_float32_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float32_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int64_t float32_to_int64(float32 a)
+{
+	if (is_float32_nan(a))
+		return INT64_MAX;
+	
+	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float32_to_uint64_helper(a);
+}
+
+/** Helper procedure for converting float64 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float64_to_uint64_helper(float64 a)
+{
+	uint64_t frac;
+	
+	if (a.parts.exp < FLOAT64_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac = a.parts.fraction;
+	
+	frac |= FLOAT64_HIDDEN_BIT_MASK;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
+	
+	frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
+	if ((a.parts.sign == 1) && (frac != 0)) {
+		frac = ~frac;
+		++frac;
+	}
+	
+	return frac;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float64_to_uint32(float64 a)
+{
+	if (is_float64_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return (uint32_t) _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float64_to_int32(float64 a)
+{
+	if (is_float64_nan(a))
+		return INT32_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return (int32_t) _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens 
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float64_to_uint64(float64 a)
+{
+	if (is_float64_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float64_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens 
+ *  - now its the biggest or the smallest int
+ */
+int64_t float64_to_int64(float64 a)
+{
+	if (is_float64_nan(a))
+		return INT64_MAX;
+	
+	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float64_to_uint64_helper(a);
+}
+
+/** Helper procedure for converting float128 to uint64.
+ *
+ * @param a Floating point number in normalized form
+ *     (NaNs or Inf are not checked).
+ * @return Converted unsigned integer.
+ */
+static uint64_t _float128_to_uint64_helper(float128 a)
+{
+	uint64_t frac_hi, frac_lo;
+	
+	if (a.parts.exp < FLOAT128_BIAS) {
+		// TODO: rounding
+		return 0;
+	}
+	
+	frac_hi = a.parts.frac_hi;
+	frac_lo = a.parts.frac_lo;
+	
+	frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
+	/* shift fraction to left so hidden bit will be the most significant bit */
+	lshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 1), &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - (a.parts.exp - FLOAT128_BIAS) - 1), &frac_hi, &frac_lo);
+	if ((a.parts.sign == 1) && !eq128(frac_hi, frac_lo, 0x0ll, 0x0ll)) {
+		not128(frac_hi, frac_lo, &frac_hi, &frac_lo);
+		add128(frac_hi, frac_lo, 0x0ll, 0x1ll, &frac_hi, &frac_lo);
+	}
+	
+	return frac_lo;
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint32_t float128_to_uint32(float128 a)
+{
+	if (is_float128_nan(a))
+		return UINT32_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return UINT32_MIN;
+		
+		return UINT32_MAX;
+	}
+	
+	return (uint32_t) _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int32_t float128_to_int32(float128 a)
+{
+	if (is_float128_nan(a))
+		return INT32_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return INT32_MIN;
+		
+		return INT32_MAX;
+	}
+	
+	return (int32_t) _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+uint64_t float128_to_uint64(float128 a)
+{
+	if (is_float128_nan(a))
+		return UINT64_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return UINT64_MIN;
+		
+		return UINT64_MAX;
+	}
+	
+	return _float128_to_uint64_helper(a);
+}
+
+/*
+ * FIXME: Im not sure what to return if overflow/underflow happens
+ *  - now its the biggest or the smallest int
+ */
+int64_t float128_to_int64(float128 a)
+{
+	if (is_float128_nan(a))
+		return INT64_MAX;
+	
+	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
+		if (a.parts.sign)
+			return INT64_MIN;
+		
+		return INT64_MAX;
+	}
+	
+	return _float128_to_uint64_helper(a);
+}
+
+float32 uint32_to_float32(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float32 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT32_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin = 0;
+		return result;
+	}
+	
+	if (counter > 0) {
+		i <<= counter - 1;
+	} else {
+		i >>= 1;
+	}
+	
+	round_float32(&exp, &i);
+	
+	result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float32 int32_to_float32(int32_t i)
+{
+	float32 result;
+	
+	if (i < 0)
+		result = uint32_to_float32((uint32_t) (-i));
+	else
+		result = uint32_to_float32((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float32 uint64_to_float32(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	uint32_t j;
+	float32 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT32_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin = 0;
+		return result;
+	}
+	
+	/* Shift all to the first 31 bits (31st will be hidden 1) */
+	if (counter > 33) {
+		i <<= counter - 1 - 32;
+	} else {
+		i >>= 1 + 32 - counter;
+	}
+	
+	j = (uint32_t) i;
+	round_float32(&exp, &j);
+	
+	result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	return result;
+}
+
+float32 int64_to_float32(int64_t i)
+{
+	float32 result;
+	
+	if (i < 0)
+		result = uint64_to_float32((uint64_t) (-i));
+	else
+		result = uint64_to_float32((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float64 uint32_to_float64(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float64 result;
+	uint64_t frac;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT64_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin = 0;
+		return result;
+	}
+	
+	frac = i;
+	frac <<= counter + 32 - 1;
+	
+	round_float64(&exp, &frac);
+	
+	result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float64 int32_to_float64(int32_t i)
+{
+	float64 result;
+	
+	if (i < 0)
+		result = uint32_to_float64((uint32_t) (-i));
+	else
+		result = uint32_to_float64((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+
+float64 uint64_to_float64(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	float64 result;
+	
+	result.parts.sign = 0;
+	result.parts.fraction = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT64_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin = 0;
+		return result;
+	}
+	
+	if (counter > 0) {
+		i <<= counter - 1;
+	} else {
+		i >>= 1;
+	}
+	
+	round_float64(&exp, &i);
+	
+	result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
+	result.parts.exp = exp;
+	return result;
+}
+
+float64 int64_to_float64(int64_t i)
+{
+	float64 result;
+	
+	if (i < 0)
+		result = uint64_to_float64((uint64_t) (-i));
+	else
+		result = uint64_to_float64((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+float128 uint32_to_float128(uint32_t i)
+{
+	int counter;
+	int32_t exp;
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = 0;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = 0;
+	
+	counter = count_zeroes32(i);
+	
+	exp = FLOAT128_BIAS + 32 - counter - 1;
+	
+	if (counter == 32) {
+		result.bin.hi = 0;
+		result.bin.lo = 0;
+		return result;
+	}
+	
+	frac_hi = 0;
+	frac_lo = i;
+	lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
+	
+	round_float128(&exp, &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float128 int32_to_float128(int32_t i)
+{
+	float128 result;
+	
+	if (i < 0)
+		result = uint32_to_float128((uint32_t) (-i));
+	else
+		result = uint32_to_float128((uint32_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+
+float128 uint64_to_float128(uint64_t i)
+{
+	int counter;
+	int32_t exp;
+	float128 result;
+	uint64_t frac_hi, frac_lo;
+	
+	result.parts.sign = 0;
+	result.parts.frac_hi = 0;
+	result.parts.frac_lo = 0;
+	
+	counter = count_zeroes64(i);
+	
+	exp = FLOAT128_BIAS + 64 - counter - 1;
+	
+	if (counter == 64) {
+		result.bin.hi = 0;
+		result.bin.lo = 0;
+		return result;
+	}
+	
+	frac_hi = 0;
+	frac_lo = i;
+	lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
+	
+	round_float128(&exp, &frac_hi, &frac_lo);
+	
+	rshift128(frac_hi, frac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
+	result.parts.frac_hi = frac_hi;
+	result.parts.frac_lo = frac_lo;
+	result.parts.exp = exp;
+	
+	return result;
+}
+
+float128 int64_to_float128(int64_t i)
+{
+	float128 result;
+	
+	if (i < 0)
+		result = uint64_to_float128((uint64_t) (-i));
+	else
+		result = uint64_to_float128((uint64_t) i);
+	
+	result.parts.sign = i < 0;
+	
+	return result;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/conversion.h
===================================================================
--- uspace/lib/softfloat/conversion.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/conversion.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,104 @@
+/*
+ * 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 Conversion of precision and conversion between integers and floats.
+ */
+
+#ifndef __CONVERSION_H__
+#define __CONVERSION_H__
+
+extern float64 float32_to_float64(float32);
+extern float96 float32_to_float96(float32);
+extern float128 float32_to_float128(float32);
+extern float96 float64_to_float96(float64);
+extern float128 float64_to_float128(float64);
+extern float128 float96_to_float128(float96);
+
+extern float32 float64_to_float32(float64);
+extern float32 float96_to_float32(float96);
+extern float64 float96_to_float64(float96);
+extern float32 float128_to_float32(float128);
+extern float64 float128_to_float64(float128);
+extern float96 float128_to_float96(float128);
+
+extern uint32_t float32_to_uint32(float32);
+extern int32_t float32_to_int32(float32);
+
+extern uint64_t float32_to_uint64(float32);
+extern int64_t float32_to_int64(float32);
+
+extern uint32_t float64_to_uint32(float64);
+extern int32_t float64_to_int32(float64);
+
+extern uint64_t float64_to_uint64(float64);
+extern int64_t float64_to_int64(float64);
+
+extern uint32_t float96_to_uint32(float96);
+extern int32_t float96_to_int32(float96);
+
+extern uint64_t float96_to_uint64(float96);
+extern int64_t float96_to_int64(float96);
+
+extern uint32_t float128_to_uint32(float128);
+extern int32_t float128_to_int32(float128);
+
+extern uint64_t float128_to_uint64(float128);
+extern int64_t float128_to_int64(float128);
+
+extern float32 uint32_to_float32(uint32_t);
+extern float32 int32_to_float32(int32_t);
+
+extern float32 uint64_to_float32(uint64_t);
+extern float32 int64_to_float32(int64_t);
+
+extern float64 uint32_to_float64(uint32_t);
+extern float64 int32_to_float64(int32_t);
+
+extern float64 uint64_to_float64(uint64_t);
+extern float64 int64_to_float64(int64_t);
+
+extern float96 uint32_to_float96(uint32_t);
+extern float96 int32_to_float96(int32_t);
+
+extern float96 uint64_to_float96(uint64_t);
+extern float96 int64_to_float96(int64_t);
+
+extern float128 uint32_to_float128(uint32_t);
+extern float128 int32_to_float128(int32_t);
+
+extern float128 uint64_to_float128(uint64_t);
+extern float128 int64_to_float128(int64_t);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/div.c
===================================================================
--- uspace/lib/softfloat/div.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/div.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,542 @@
+/*
+ * 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 Division functions.
+ */
+
+#include "sftypes.h"
+#include "add.h"
+#include "div.h"
+#include "comparison.h"
+#include "mul.h"
+#include "common.h"
+
+/** Divide two single-precision floats.
+ *
+ * @param a Nominator.
+ * @param b Denominator.
+ *
+ * @return Result of division.
+ *
+ */
+float32 div_float32(float32 a, float32 b)
+{
+	float32 result;
+	int32_t aexp, bexp, cexp;
+	uint64_t afrac, bfrac, cfrac;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float32_nan(a)) {
+		if (is_float32_signan(a)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return a;
+	}
+	
+	if (is_float32_nan(b)) {
+		if (is_float32_signan(b)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return b;
+	}
+	
+	if (is_float32_infinity(a)) {
+		if (is_float32_infinity(b)) {
+			/*FIXME: inf / inf */
+			result.bin = FLOAT32_NAN;
+			return result;
+		}
+		/* inf / num */
+		result.parts.exp = a.parts.exp;
+		result.parts.fraction = a.parts.fraction;
+		return result;
+	}
+	
+	if (is_float32_infinity(b)) {
+		if (is_float32_zero(a)) {
+			/* FIXME 0 / inf */
+			result.parts.exp = 0;
+			result.parts.fraction = 0;
+			return result;
+		}
+		/* FIXME: num / inf*/
+		result.parts.exp = 0;
+		result.parts.fraction = 0;
+		return result;
+	}
+	
+	if (is_float32_zero(b)) {
+		if (is_float32_zero(a)) {
+			/*FIXME: 0 / 0*/
+			result.bin = FLOAT32_NAN;
+			return result;
+		}
+		/* FIXME: division by zero */
+		result.parts.exp = 0;
+		result.parts.fraction = 0;
+		return result;
+	}
+	
+	afrac = a.parts.fraction;
+	aexp = a.parts.exp;
+	bfrac = b.parts.fraction;
+	bexp = b.parts.exp;
+	
+	/* denormalized numbers */
+	if (aexp == 0) {
+		if (afrac == 0) {
+			result.parts.exp = 0;
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* normalize it*/
+		afrac <<= 1;
+		/* afrac is nonzero => it must stop */
+		while (!(afrac & FLOAT32_HIDDEN_BIT_MASK)) {
+			afrac <<= 1;
+			aexp--;
+		}
+	}
+	
+	if (bexp == 0) {
+		bfrac <<= 1;
+		/* bfrac is nonzero => it must stop */
+		while (!(bfrac & FLOAT32_HIDDEN_BIT_MASK)) {
+			bfrac <<= 1;
+			bexp--;
+		}
+	}
+	
+	afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK) << (32 - FLOAT32_FRACTION_SIZE - 1);
+	bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK) << (32 - FLOAT32_FRACTION_SIZE);
+	
+	if (bfrac <= (afrac << 1)) {
+		afrac >>= 1;
+		aexp++;
+	}
+	
+	cexp = aexp - bexp + FLOAT32_BIAS - 2;
+	
+	cfrac = (afrac << 32) / bfrac;
+	if ((cfrac & 0x3F) == 0) { 
+		cfrac |= (bfrac * cfrac != afrac << 32);
+	}
+	
+	/* pack and round */
+	
+	/* find first nonzero digit and shift result and detect possibly underflow */
+	while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)))) {
+		cexp--;
+		cfrac <<= 1;
+		/* TODO: fix underflow */
+	}
+	
+	cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
+	
+	if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
+		++cexp;
+		cfrac >>= 1;
+	}
+	
+	/* check overflow */
+	if (cexp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow, return infinity */
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		result.parts.fraction = 0;
+		return result;
+	}
+	
+	if (cexp < 0) {
+		/* FIXME: underflow */
+		result.parts.exp = 0;
+		if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
+			result.parts.fraction = 0;
+			return result;
+		}
+		cfrac >>= 1;
+		while (cexp < 0) {
+			cexp++;
+			cfrac >>= 1;
+		}
+	} else {
+		result.parts.exp = (uint32_t) cexp;
+	}
+	
+	result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
+	
+	return result;
+}
+
+/** Divide two double-precision floats.
+ *
+ * @param a Nominator.
+ * @param b Denominator.
+ *
+ * @return Result of division.
+ *
+ */
+float64 div_float64(float64 a, float64 b) 
+{
+	float64 result;
+	int64_t aexp, bexp, cexp;
+	uint64_t afrac, bfrac, cfrac; 
+	uint64_t remlo, remhi;
+	uint64_t tmplo, tmphi;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float64_nan(a)) {
+		if (is_float64_signan(b)) {
+			// FIXME: SigNaN
+			return b;
+		}
+		
+		if (is_float64_signan(a)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return a;
+	}
+	
+	if (is_float64_nan(b)) {
+		if (is_float64_signan(b)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return b;
+	}
+	
+	if (is_float64_infinity(a)) {
+		if (is_float64_infinity(b) || is_float64_zero(b)) {
+			// FIXME: inf / inf
+			result.bin = FLOAT64_NAN;
+			return result;
+		}
+		/* inf / num */
+		result.parts.exp = a.parts.exp;
+		result.parts.fraction = a.parts.fraction;
+		return result;
+	}
+	
+	if (is_float64_infinity(b)) {
+		if (is_float64_zero(a)) {
+			/* FIXME 0 / inf */
+			result.parts.exp = 0;
+			result.parts.fraction = 0;
+			return result;
+		}
+		/* FIXME: num / inf*/
+		result.parts.exp = 0;
+		result.parts.fraction = 0;
+		return result;
+	}
+	
+	if (is_float64_zero(b)) {
+		if (is_float64_zero(a)) {
+			/*FIXME: 0 / 0*/
+			result.bin = FLOAT64_NAN;
+			return result;
+		}
+		/* FIXME: division by zero */
+		result.parts.exp = 0;
+		result.parts.fraction = 0;
+		return result;
+	}
+	
+	afrac = a.parts.fraction;
+	aexp = a.parts.exp;
+	bfrac = b.parts.fraction;
+	bexp = b.parts.exp;
+	
+	/* denormalized numbers */
+	if (aexp == 0) {
+		if (afrac == 0) {
+			result.parts.exp = 0;
+			result.parts.fraction = 0;
+			return result;
+		}
+		
+		/* normalize it*/
+		aexp++;
+		/* afrac is nonzero => it must stop */	
+		while (!(afrac & FLOAT64_HIDDEN_BIT_MASK)) {
+			afrac <<= 1;
+			aexp--;
+		}
+	}
+	
+	if (bexp == 0) {
+		bexp++;
+		/* bfrac is nonzero => it must stop */	
+		while (!(bfrac & FLOAT64_HIDDEN_BIT_MASK)) {
+			bfrac <<= 1;
+			bexp--;
+		}
+	}
+	
+	afrac = (afrac | FLOAT64_HIDDEN_BIT_MASK) << (64 - FLOAT64_FRACTION_SIZE - 2);
+	bfrac = (bfrac | FLOAT64_HIDDEN_BIT_MASK) << (64 - FLOAT64_FRACTION_SIZE - 1);
+	
+	if (bfrac <= (afrac << 1)) {
+		afrac >>= 1;
+		aexp++;
+	}
+	
+	cexp = aexp - bexp + FLOAT64_BIAS - 2; 
+	
+	cfrac = div128est(afrac, 0x0ll, bfrac);
+	
+	if ((cfrac & 0x1FF) <= 2) {
+		mul64(bfrac, cfrac, &tmphi, &tmplo);
+		sub128(afrac, 0x0ll, tmphi, tmplo, &remhi, &remlo);
+		
+		while ((int64_t) remhi < 0) {
+			cfrac--;
+			add128(remhi, remlo, 0x0ll, bfrac, &remhi, &remlo);
+		}
+		cfrac |= (remlo != 0);
+	}
+	
+	/* round and shift */
+	result = finish_float64(cexp, cfrac, result.parts.sign);
+	return result;
+}
+
+/** Divide two quadruple-precision floats.
+ *
+ * @param a Nominator.
+ * @param b Denominator.
+ *
+ * @return Result of division.
+ *
+ */
+float128 div_float128(float128 a, float128 b)
+{
+	float128 result;
+	int64_t aexp, bexp, cexp;
+	uint64_t afrac_hi, afrac_lo, bfrac_hi, bfrac_lo, cfrac_hi, cfrac_lo;
+	uint64_t shift_out;
+	uint64_t rem_hihi, rem_hilo, rem_lohi, rem_lolo;
+	uint64_t tmp_hihi, tmp_hilo, tmp_lohi, tmp_lolo;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float128_nan(a)) {
+		if (is_float128_signan(b)) {
+			// FIXME: SigNaN
+			return b;
+		}
+		
+		if (is_float128_signan(a)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return a;
+	}
+	
+	if (is_float128_nan(b)) {
+		if (is_float128_signan(b)) {
+			// FIXME: SigNaN
+		}
+		/* NaN */
+		return b;
+	}
+	
+	if (is_float128_infinity(a)) {
+		if (is_float128_infinity(b) || is_float128_zero(b)) {
+			// FIXME: inf / inf
+			result.bin.hi = FLOAT128_NAN_HI;
+			result.bin.lo = FLOAT128_NAN_LO;
+			return result;
+		}
+		/* inf / num */
+		result.parts.exp = a.parts.exp;
+		result.parts.frac_hi = a.parts.frac_hi;
+		result.parts.frac_lo = a.parts.frac_lo;
+		return result;
+	}
+	
+	if (is_float128_infinity(b)) {
+		if (is_float128_zero(a)) {
+			// FIXME 0 / inf
+			result.parts.exp = 0;
+			result.parts.frac_hi = 0;
+			result.parts.frac_lo = 0;
+			return result;
+		}
+		// FIXME: num / inf
+		result.parts.exp = 0;
+		result.parts.frac_hi = 0;
+		result.parts.frac_lo = 0;
+		return result;
+	}
+	
+	if (is_float128_zero(b)) {
+		if (is_float128_zero(a)) {
+			// FIXME: 0 / 0
+			result.bin.hi = FLOAT128_NAN_HI;
+			result.bin.lo = FLOAT128_NAN_LO;
+			return result;
+		}
+		// FIXME: division by zero
+		result.parts.exp = 0;
+		result.parts.frac_hi = 0;
+		result.parts.frac_lo = 0;
+		return result;
+	}
+	
+	afrac_hi = a.parts.frac_hi;
+	afrac_lo = a.parts.frac_lo;
+	aexp = a.parts.exp;
+	bfrac_hi = b.parts.frac_hi;
+	bfrac_lo = b.parts.frac_lo;
+	bexp = b.parts.exp;
+	
+	/* denormalized numbers */
+	if (aexp == 0) {
+		if (eq128(afrac_hi, afrac_lo, 0x0ll, 0x0ll)) {
+			result.parts.exp = 0;
+			result.parts.frac_hi = 0;
+			result.parts.frac_lo = 0;
+			return result;
+		}
+		
+		/* normalize it*/
+		aexp++;
+		/* afrac is nonzero => it must stop */
+		and128(afrac_hi, afrac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hihi, &tmp_lolo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hihi, tmp_lolo)) {
+			lshift128(afrac_hi, afrac_lo, 1, &afrac_hi, &afrac_lo);
+			aexp--;
+		}
+	}
+	
+	if (bexp == 0) {
+		bexp++;
+		/* bfrac is nonzero => it must stop */
+		and128(bfrac_hi, bfrac_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &tmp_hihi, &tmp_lolo);
+		while (!lt128(0x0ll, 0x0ll, tmp_hihi, tmp_lolo)) {
+			lshift128(bfrac_hi, bfrac_lo, 1, &bfrac_hi, &bfrac_lo);
+			bexp--;
+		}
+	}
+	
+	or128(afrac_hi, afrac_lo,
+	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &afrac_hi, &afrac_lo);
+	lshift128(afrac_hi, afrac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 1), &afrac_hi, &afrac_lo);
+	or128(bfrac_hi, bfrac_lo,
+	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &bfrac_hi, &bfrac_lo);
+	lshift128(bfrac_hi, bfrac_lo,
+	    (128 - FLOAT128_FRACTION_SIZE - 1), &bfrac_hi, &bfrac_lo);
+	
+	if (le128(bfrac_hi, bfrac_lo, afrac_hi, afrac_lo)) {
+		rshift128(afrac_hi, afrac_lo, 1, &afrac_hi, &afrac_lo);
+		aexp++;
+	}
+	
+	cexp = aexp - bexp + FLOAT128_BIAS - 2;
+	
+	cfrac_hi = div128est(afrac_hi, afrac_lo, bfrac_hi);
+	
+	mul128(bfrac_hi, bfrac_lo, 0x0ll, cfrac_hi,
+	    &tmp_lolo /* dummy */, &tmp_hihi, &tmp_hilo, &tmp_lohi);
+	
+	/* sub192(afrac_hi, afrac_lo, 0,
+	 *     tmp_hihi, tmp_hilo, tmp_lohi
+	 *     &rem_hihi, &rem_hilo, &rem_lohi); */
+	sub128(afrac_hi, afrac_lo, tmp_hihi, tmp_hilo, &rem_hihi, &rem_hilo);
+	if (tmp_lohi > 0) {
+		sub128(rem_hihi, rem_hilo, 0x0ll, 0x1ll, &rem_hihi, &rem_hilo);
+	}
+	rem_lohi = -tmp_lohi;
+	
+	while ((int64_t) rem_hihi < 0) {
+		--cfrac_hi;
+		/* add192(rem_hihi, rem_hilo, rem_lohi,
+		 *     0, bfrac_hi, bfrac_lo,
+		 *     &rem_hihi, &rem_hilo, &rem_lohi); */
+		add128(rem_hilo, rem_lohi, bfrac_hi, bfrac_lo, &rem_hilo, &rem_lohi);
+		if (lt128(rem_hilo, rem_lohi, bfrac_hi, bfrac_lo)) {
+			++rem_hihi;
+		}
+	}
+	
+	cfrac_lo = div128est(rem_hilo, rem_lohi, bfrac_lo);
+	
+	if ((cfrac_lo & 0x3FFF) <= 4) {
+		mul128(bfrac_hi, bfrac_lo, 0x0ll, cfrac_lo,
+		    &tmp_hihi /* dummy */, &tmp_hilo, &tmp_lohi, &tmp_lolo);
+		
+		/* sub192(rem_hilo, rem_lohi, 0,
+		 *     tmp_hilo, tmp_lohi, tmp_lolo,
+		 *     &rem_hilo, &rem_lohi, &rem_lolo); */
+		sub128(rem_hilo, rem_lohi, tmp_hilo, tmp_lohi, &rem_hilo, &rem_lohi);
+		if (tmp_lolo > 0) {
+			sub128(rem_hilo, rem_lohi, 0x0ll, 0x1ll, &rem_hilo, &rem_lohi);
+		}
+		rem_lolo = -tmp_lolo;
+		
+		while ((int64_t) rem_hilo < 0) {
+			--cfrac_lo;
+			/* add192(rem_hilo, rem_lohi, rem_lolo,
+			 *     0, bfrac_hi, bfrac_lo,
+			 *     &rem_hilo, &rem_lohi, &rem_lolo); */
+			add128(rem_lohi, rem_lolo, bfrac_hi, bfrac_lo, &rem_lohi, &rem_lolo);
+			if (lt128(rem_lohi, rem_lolo, bfrac_hi, bfrac_lo)) {
+				++rem_hilo;
+			}
+		}
+		
+		cfrac_lo |= ((rem_hilo | rem_lohi | rem_lolo) != 0 );
+	}
+	
+	shift_out = cfrac_lo << (64 - (128 - FLOAT128_FRACTION_SIZE - 1));
+	rshift128(cfrac_hi, cfrac_lo, (128 - FLOAT128_FRACTION_SIZE - 1),
+	    &cfrac_hi, &cfrac_lo);
+	
+	result = finish_float128(cexp, cfrac_hi, cfrac_lo, result.parts.sign, shift_out);
+	return result;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/div.h
===================================================================
--- uspace/lib/softfloat/div.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/div.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,47 @@
+/*
+ * 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 Division functions.
+ */
+
+#ifndef __DIV_H__
+#define __DIV_H__
+
+extern float32 div_float32(float32, float32);
+extern float64 div_float64(float64, float64);
+extern float96 div_float96(float96, float96);
+extern float128 div_float128(float128, float128);
+
+#endif
+
+/** @}
+ */
Index: pace/lib/softfloat/generic/add.c
===================================================================
--- uspace/lib/softfloat/generic/add.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,416 +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 Addition functions.
- */
-
-#include <sftypes.h>
-#include <add.h>
-#include <comparison.h>
-#include <common.h>
-
-/** Add two single-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- * @return Result of addition.
- */
-float32 add_float32(float32 a, float32 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2, frac1, frac2;
-	
-	expdiff = a.parts.exp - b.parts.exp;
-	if (expdiff < 0) {
-		if (is_float32_nan(b)) {
-			/* TODO: fix SigNaN */
-			if (is_float32_signan(b)) {
-			}
-
-			return b;
-		}
-		
-		if (b.parts.exp == FLOAT32_MAX_EXPONENT) { 
-			return b;
-		}
-		
-		frac1 = b.parts.fraction;
-		exp1 = b.parts.exp;
-		frac2 = a.parts.fraction;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if ((is_float32_nan(a)) || (is_float32_nan(b))) {
-			/* TODO: fix SigNaN */
-			if (is_float32_signan(a) || is_float32_signan(b)) {
-			}
-			return (is_float32_nan(a) ? a : b);
-		}
-		
-		if (a.parts.exp == FLOAT32_MAX_EXPONENT) { 
-			return a;
-		}
-		
-		frac1 = a.parts.fraction;
-		exp1 = a.parts.exp;
-		frac2 = b.parts.fraction;
-		exp2 = b.parts.exp;
-	}
-	
-	if (exp1 == 0) {
-		/* both are denormalized */
-		frac1 += frac2;
-		if (frac1 & FLOAT32_HIDDEN_BIT_MASK ) {
-			/* result is not denormalized */
-			a.parts.exp = 1;
-		}
-		a.parts.fraction = frac1;
-		return a;
-	}
-	
-	frac1 |= FLOAT32_HIDDEN_BIT_MASK; /* add hidden bit */
-
-	if (exp2 == 0) {
-		/* second operand is denormalized */
-		--expdiff;
-	} else {
-		/* add hidden bit to second operand */
-		frac2 |= FLOAT32_HIDDEN_BIT_MASK; 
-	}
-	
-	/* create some space for rounding */
-	frac1 <<= 6;
-	frac2 <<= 6;
-	
-	if (expdiff < (FLOAT32_FRACTION_SIZE + 2) ) {
-		frac2 >>= expdiff;
-		frac1 += frac2;
-	} else {
-		a.parts.exp = exp1;
-		a.parts.fraction = (frac1 >> 6) & (~(FLOAT32_HIDDEN_BIT_MASK));
-		return a;
-	}
-	
-	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	/* rounding - if first bit after fraction is set then round up */
-	frac1 += (0x1 << 5);
-	
-	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) { 
-		/* rounding overflow */
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	if ((exp1 == FLOAT32_MAX_EXPONENT ) || (exp2 > exp1)) {
-		/* overflow - set infinity as result */
-		a.parts.exp = FLOAT32_MAX_EXPONENT;
-		a.parts.fraction = 0;
-		return a;
-	}
-	
-	a.parts.exp = exp1;
-	
-	/* Clear hidden bit and shift */
-	a.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
-	return a;
-}
-
-/** Add two double-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- * @return Result of addition.
- */
-float64 add_float64(float64 a, float64 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2;
-	uint64_t frac1, frac2;
-	
-	expdiff = ((int) a.parts.exp) - b.parts.exp;
-	if (expdiff < 0) {
-		if (is_float64_nan(b)) {
-			/* TODO: fix SigNaN */
-			if (is_float64_signan(b)) {
-			}
-
-			return b;
-		}
-		
-		/* b is infinity and a not */
-		if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
-			return b;
-		}
-		
-		frac1 = b.parts.fraction;
-		exp1 = b.parts.exp;
-		frac2 = a.parts.fraction;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if (is_float64_nan(a)) {
-			/* TODO: fix SigNaN */
-			if (is_float64_signan(a) || is_float64_signan(b)) {
-			}
-			return a;
-		}
-		
-		/* a is infinity and b not */
-		if (a.parts.exp == FLOAT64_MAX_EXPONENT) { 
-			return a;
-		}
-		
-		frac1 = a.parts.fraction;
-		exp1 = a.parts.exp;
-		frac2 = b.parts.fraction;
-		exp2 = b.parts.exp;
-	}
-	
-	if (exp1 == 0) {
-		/* both are denormalized */
-		frac1 += frac2;
-		if (frac1 & FLOAT64_HIDDEN_BIT_MASK) { 
-			/* result is not denormalized */
-			a.parts.exp = 1;
-		}
-		a.parts.fraction = frac1;
-		return a;
-	}
-	
-	/* add hidden bit - frac1 is sure not denormalized */
-	frac1 |= FLOAT64_HIDDEN_BIT_MASK;
-
-	/* second operand ... */
-	if (exp2 == 0) {
-		/* ... is denormalized */
-		--expdiff;	
-	} else {
-		/* is not denormalized */
-		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
-	}
-	
-	/* create some space for rounding */
-	frac1 <<= 6;
-	frac2 <<= 6;
-	
-	if (expdiff < (FLOAT64_FRACTION_SIZE + 2)) {
-		frac2 >>= expdiff;
-		frac1 += frac2;
-	} else {
-		a.parts.exp = exp1;
-		a.parts.fraction = (frac1 >> 6) & (~(FLOAT64_HIDDEN_BIT_MASK));
-		return a;
-	}
-	
-	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	/* rounding - if first bit after fraction is set then round up */
-	frac1 += (0x1 << 5); 
-	
-	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) { 
-		/* rounding overflow */
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	if ((exp1 == FLOAT64_MAX_EXPONENT ) || (exp2 > exp1)) {
-		/* overflow - set infinity as result */
-		a.parts.exp = FLOAT64_MAX_EXPONENT;
-		a.parts.fraction = 0;
-		return a;
-	}
-	
-	a.parts.exp = exp1;
-	/* Clear hidden bit and shift */
-	a.parts.fraction = ((frac1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
-	return a;
-}
-
-/** Add two quadruple-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- * @return Result of addition.
- */
-float128 add_float128(float128 a, float128 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2;
-	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
-
-	expdiff = ((int) a.parts.exp) - b.parts.exp;
-	if (expdiff < 0) {
-		if (is_float128_nan(b)) {
-			/* TODO: fix SigNaN */
-			if (is_float128_signan(b)) {
-			}
-
-			return b;
-		}
-
-		/* b is infinity and a not */
-		if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
-			return b;
-		}
-
-		frac1_hi = b.parts.frac_hi;
-		frac1_lo = b.parts.frac_lo;
-		exp1 = b.parts.exp;
-		frac2_hi = a.parts.frac_hi;
-		frac2_lo = a.parts.frac_lo;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if (is_float128_nan(a)) {
-			/* TODO: fix SigNaN */
-			if (is_float128_signan(a) || is_float128_signan(b)) {
-			}
-			return a;
-		}
-
-		/* a is infinity and b not */
-		if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
-			return a;
-		}
-
-		frac1_hi = a.parts.frac_hi;
-		frac1_lo = a.parts.frac_lo;
-		exp1 = a.parts.exp;
-		frac2_hi = b.parts.frac_hi;
-		frac2_lo = b.parts.frac_lo;
-		exp2 = b.parts.exp;
-	}
-
-	if (exp1 == 0) {
-		/* both are denormalized */
-		add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
-
-		and128(frac1_hi, frac1_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hi, &tmp_lo);
-		if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-			/* result is not denormalized */
-			a.parts.exp = 1;
-		}
-
-		a.parts.frac_hi = frac1_hi;
-		a.parts.frac_lo = frac1_lo;
-		return a;
-	}
-
-	/* add hidden bit - frac1 is sure not denormalized */
-	or128(frac1_hi, frac1_lo,
-	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &frac1_hi, &frac1_lo);
-
-	/* second operand ... */
-	if (exp2 == 0) {
-		/* ... is denormalized */
-		--expdiff;
-	} else {
-		/* is not denormalized */
-		or128(frac2_hi, frac2_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &frac2_hi, &frac2_lo);
-	}
-
-	/* create some space for rounding */
-	lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
-	lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
-
-	if (expdiff < (FLOAT128_FRACTION_SIZE + 2)) {
-		rshift128(frac2_hi, frac2_lo, expdiff, &frac2_hi, &frac2_lo);
-		add128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &frac1_hi, &frac1_lo);
-	} else {
-		a.parts.exp = exp1;
-
-		rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
-		not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hi, &tmp_lo);
-		and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-
-		a.parts.frac_hi = tmp_hi;
-		a.parts.frac_lo = tmp_lo;
-		return a;
-	}
-
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
-	    &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-		++exp1;
-		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
-	}
-
-	/* rounding - if first bit after fraction is set then round up */
-	add128(frac1_hi, frac1_lo, 0x0ll, 0x1ll << 5, &frac1_hi, &frac1_lo);
-
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
-	   &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-		/* rounding overflow */
-		++exp1;
-		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
-	}
-
-	if ((exp1 == FLOAT128_MAX_EXPONENT ) || (exp2 > exp1)) {
-		/* overflow - set infinity as result */
-		a.parts.exp = FLOAT64_MAX_EXPONENT;
-		a.parts.frac_hi = 0;
-		a.parts.frac_lo = 0;
-		return a;
-	}
-
-	a.parts.exp = exp1;
-	
-	/* Clear hidden bit and shift */
-	rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
-	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-
-	a.parts.frac_hi = tmp_hi;
-	a.parts.frac_lo = tmp_lo;
-
-	return a;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/common.c
===================================================================
--- uspace/lib/softfloat/generic/common.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,690 +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 Common helper operations.
- */
-
-#include <sftypes.h>
-#include <common.h>
-
-/* Table for fast leading zeroes counting. */
-char zeroTable[256] = {
-	8, 7, 7, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, \
-	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, \
-	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
-	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/** 
- * Take fraction shifted by 10 bits to the left, round it, normalize it
- * and detect exceptions
- * 
- * @param cexp Exponent with bias.
- * @param cfrac Fraction shifted 10 bits to the left with added hidden bit.
- * @param sign Resulting sign.
- * @return Finished double-precision float.
- */
-float64 finish_float64(int32_t cexp, uint64_t cfrac, char sign)
-{
-	float64 result;
-
-	result.parts.sign = sign;
-
-	/* find first nonzero digit and shift result and detect possibly underflow */
-	while ((cexp > 0) && (cfrac) &&
-	    (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1))))) {
-		cexp--; 
-		cfrac <<= 1;
-		/* TODO: fix underflow */
-	}
-	
-	if ((cexp < 0) || (cexp == 0 &&
-	    (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))))) {
-		/* FIXME: underflow */
-		result.parts.exp = 0;
-		if ((cexp + FLOAT64_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		while (cexp < 0) {
-			cexp++;
-			cfrac >>= 1;
-		}
-	
-		cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3)); 
-		
-		if (!(cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1)))) {
-			result.parts.fraction =
-			    ((cfrac >> (64 - FLOAT64_FRACTION_SIZE - 2)) & (~FLOAT64_HIDDEN_BIT_MASK));
-			return result;
-		}	
-	} else {
-		cfrac += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3)); 
-	}
-	
-	++cexp;
-
-	if (cfrac & (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 1))) {
-		++cexp;
-		cfrac >>= 1;
-	}	
-
-	/* check overflow */
-	if (cexp >= FLOAT64_MAX_EXPONENT) {
-		/* FIXME: overflow, return infinity */
-		result.parts.exp = FLOAT64_MAX_EXPONENT;
-		result.parts.fraction = 0;
-		return result;
-	}
-
-	result.parts.exp = (uint32_t) cexp;
-	
-	result.parts.fraction = 
-	    ((cfrac >> (64 - FLOAT64_FRACTION_SIZE - 2)) & (~FLOAT64_HIDDEN_BIT_MASK));
-	
-	return result;	
-}
-
-/**
- * Take fraction, round it, normalize it and detect exceptions
- * 
- * @param cexp Exponent with bias.
- * @param cfrac_hi High part of the fraction shifted 14 bits to the left
- *     with added hidden bit.
- * @param cfrac_lo Low part of the fraction shifted 14 bits to the left
- *     with added hidden bit.
- * @param sign Resulting sign.
- * @param shift_out Bits right-shifted out from fraction by the caller.
- * @return Finished quadruple-precision float.
- */
-float128 finish_float128(int32_t cexp, uint64_t cfrac_hi, uint64_t cfrac_lo, 
-    char sign, uint64_t shift_out)
-{
-	float128 result;
-	uint64_t tmp_hi, tmp_lo;
-
-	result.parts.sign = sign;
-
-	/* find first nonzero digit and shift result and detect possibly underflow */
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    1, &tmp_hi, &tmp_lo);
-	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	while ((cexp > 0) && (lt128(0x0ll, 0x0ll, cfrac_hi, cfrac_lo)) &&
-	    (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo))) {
-		cexp--;
-		lshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
-		/* TODO: fix underflow */
-
-		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    1, &tmp_hi, &tmp_lo);
-		and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	}
-
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    1, &tmp_hi, &tmp_lo);
-	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if ((cexp < 0) || (cexp == 0 &&
-	    (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)))) {
-		/* FIXME: underflow */
-		result.parts.exp = 0;
-		if ((cexp + FLOAT128_FRACTION_SIZE + 1) < 0) { /* +1 is place for rounding */
-			result.parts.frac_hi = 0x0ll;
-			result.parts.frac_lo = 0x0ll;
-			return result;
-		}
-
-		while (cexp < 0) {
-			cexp++;
-			rshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
-		}
-
-		if (shift_out & (0x1ull < 64)) {
-			add128(cfrac_hi, cfrac_lo, 0x0ll, 0x1ll, &cfrac_hi, &cfrac_lo);
-		}
-
-		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    1, &tmp_hi, &tmp_lo);
-		and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-		if (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-			not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-			    &tmp_hi, &tmp_lo);
-			and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-			result.parts.frac_hi = tmp_hi;
-			result.parts.frac_lo = tmp_lo;
-			return result;
-		}
-	} else {
-		if (shift_out & (0x1ull < 64)) {
-			add128(cfrac_hi, cfrac_lo, 0x0ll, 0x1ll, &cfrac_hi, &cfrac_lo);
-		}
-	}
-
-	++cexp;
-
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    1, &tmp_hi, &tmp_lo);
-	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-		++cexp;
-		rshift128(cfrac_hi, cfrac_lo, 1, &cfrac_hi, &cfrac_lo);
-	}
-
-	/* check overflow */
-	if (cexp >= FLOAT128_MAX_EXPONENT) {
-		/* FIXME: overflow, return infinity */
-		result.parts.exp = FLOAT128_MAX_EXPONENT;
-		result.parts.frac_hi = 0x0ll;
-		result.parts.frac_lo = 0x0ll;
-		return result;
-	}
-
-	result.parts.exp = (uint32_t) cexp;
-
-	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &tmp_hi, &tmp_lo);
-	and128(cfrac_hi, cfrac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	result.parts.frac_hi = tmp_hi;
-	result.parts.frac_lo = tmp_lo;
-
-	return result;	
-}
-
-/**
- * Counts leading zeroes in byte.
- *
- * @param i Byte for which to count leading zeroes.
- * @return Number of detected leading zeroes.
- */
-int count_zeroes8(uint8_t i)
-{
-	return zeroTable[i];
-}
-
-/** 
- * Counts leading zeroes in 32bit unsigned integer.
- *
- * @param i Integer for which to count leading zeroes.
- * @return Number of detected leading zeroes.
- */
-int count_zeroes32(uint32_t i)
-{
-	int j;
-	for (j = 0; j < 32; j += 8) {
-		if (i & (0xFF << (24 - j))) {
-			return (j + count_zeroes8(i >> (24 - j)));
-		}
-	}
-
-	return 32;
-}
-
-/**
- * Counts leading zeroes in 64bit unsigned integer.
- *
- * @param i Integer for which to count leading zeroes.
- * @return Number of detected leading zeroes.
- */
-int count_zeroes64(uint64_t i)
-{
-	int j;
-	for (j = 0; j < 64; j += 8) {
-		if (i & (0xFFll << (56 - j))) {
-			return (j + count_zeroes8(i >> (56 - j)));
-		}
-	}
-
-	return 64;
-}
-
-/**
- * Round and normalize number expressed by exponent and fraction with
- * first bit (equal to hidden bit) at 30th bit.
- *
- * @param exp Exponent part.
- * @param fraction Fraction with hidden bit shifted to 30th bit.
- */
-void round_float32(int32_t *exp, uint32_t *fraction)
-{
-	/* rounding - if first bit after fraction is set then round up */
-	(*fraction) += (0x1 << (32 - FLOAT32_FRACTION_SIZE - 3));
-	
-	if ((*fraction) & 
-	    (FLOAT32_HIDDEN_BIT_MASK << (32 - FLOAT32_FRACTION_SIZE - 1))) {
-		/* rounding overflow */
-		++(*exp);
-		(*fraction) >>= 1;
-	}
-	
-	if (((*exp) >= FLOAT32_MAX_EXPONENT) || ((*exp) < 0)) {
-		/* overflow - set infinity as result */
-		(*exp) = FLOAT32_MAX_EXPONENT;
-		(*fraction) = 0;
-	}
-}
-
-/**
- * Round and normalize number expressed by exponent and fraction with
- * first bit (equal to hidden bit) at 62nd bit.
- *
- * @param exp Exponent part.
- * @param fraction Fraction with hidden bit shifted to 62nd bit.
- */
-void round_float64(int32_t *exp, uint64_t *fraction)
-{
-	/* rounding - if first bit after fraction is set then round up */
-	(*fraction) += (0x1 << (64 - FLOAT64_FRACTION_SIZE - 3));
-	
-	if ((*fraction) & 
-	    (FLOAT64_HIDDEN_BIT_MASK << (64 - FLOAT64_FRACTION_SIZE - 3))) {
-		/* rounding overflow */
-		++(*exp);
-		(*fraction) >>= 1;
-	}
-	
-	if (((*exp) >= FLOAT64_MAX_EXPONENT) || ((*exp) < 0)) {
-		/* overflow - set infinity as result */
-		(*exp) = FLOAT64_MAX_EXPONENT;
-		(*fraction) = 0;
-	}
-}
-
-/**
- * Round and normalize number expressed by exponent and fraction with
- * first bit (equal to hidden bit) at 126th bit.
- *
- * @param exp Exponent part.
- * @param frac_hi High part of fraction part with hidden bit shifted to 126th bit.
- * @param frac_lo Low part of fraction part with hidden bit shifted to 126th bit.
- */
-void round_float128(int32_t *exp, uint64_t *frac_hi, uint64_t *frac_lo)
-{
-	uint64_t tmp_hi, tmp_lo;
-
-	/* rounding - if first bit after fraction is set then round up */
-	lshift128(0x0ll, 0x1ll, (128 - FLOAT128_FRACTION_SIZE - 3), &tmp_hi, &tmp_lo);
-	add128(*frac_hi, *frac_lo, tmp_hi, tmp_lo, frac_hi, frac_lo);
-
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    (128 - FLOAT128_FRACTION_SIZE - 3), &tmp_hi, &tmp_lo);
-	and128(*frac_hi, *frac_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-		/* rounding overflow */
-		++(*exp);
-		rshift128(*frac_hi, *frac_lo, 1, frac_hi, frac_lo);
-	}
-
-	if (((*exp) >= FLOAT128_MAX_EXPONENT) || ((*exp) < 0)) {
-		/* overflow - set infinity as result */
-		(*exp) = FLOAT128_MAX_EXPONENT;
-		(*frac_hi) = 0;
-		(*frac_lo) = 0;
-	}
-}
-
-/**
- * Logical shift left on the 128-bit operand.
- *
- * @param a_hi High part of the input operand.
- * @param a_lo Low part of the input operand.
- * @param shift Number of bits by witch to shift.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void lshift128(
-    uint64_t a_hi, uint64_t a_lo, int shift,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	if (shift <= 0) {
-		/* do nothing */
-	} else if (shift >= 128) {
-		a_hi = 0;
-		a_lo = 0;
-	} else if (shift >= 64) {
-		a_hi = a_lo << (shift - 64);
-		a_lo = 0;
-	} else {
-		a_hi <<= shift;
-		a_hi |= a_lo >> (64 - shift);
-		a_lo <<= shift;
-	}
-
-	*r_hi = a_hi;
-	*r_lo = a_lo;
-}
-
-/**
- * Logical shift right on the 128-bit operand.
- *
- * @param a_hi High part of the input operand.
- * @param a_lo Low part of the input operand.
- * @param shift Number of bits by witch to shift.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void rshift128(
-    uint64_t a_hi, uint64_t a_lo, int shift,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	if (shift <= 0) {
-		/* do nothing */
-	} else 	if (shift >= 128) {
-		a_hi = 0;
-		a_lo = 0;
-	} else if (shift >= 64) {
-		a_lo = a_hi >> (shift - 64);
-		a_hi = 0;
-	} else {
-		a_lo >>= shift;
-		a_lo |= a_hi << (64 - shift);
-		a_hi >>= shift;
-	}
-
-	*r_hi = a_hi;
-	*r_lo = a_lo;
-}
-
-/**
- * Bitwise AND on 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void and128(
-    uint64_t a_hi, uint64_t a_lo,
-    uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	*r_hi = a_hi & b_hi;
-	*r_lo = a_lo & b_lo;
-}
-
-/**
- * Bitwise inclusive OR on 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void or128(
-    uint64_t a_hi, uint64_t a_lo,
-    uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	*r_hi = a_hi | b_hi;
-	*r_lo = a_lo | b_lo;
-}
-
-/**
- * Bitwise exclusive OR on 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void xor128(
-    uint64_t a_hi, uint64_t a_lo,
-    uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	*r_hi = a_hi ^ b_hi;
-	*r_lo = a_lo ^ b_lo;
-}
-
-/**
- * Bitwise NOT on the 128-bit operand.
- *
- * @param a_hi High part of the input operand.
- * @param a_lo Low part of the input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void not128(
-    uint64_t a_hi, uint64_t a_lo,
-	uint64_t *r_hi, uint64_t *r_lo)
-{
-	*r_hi = ~a_hi;
-	*r_lo = ~a_lo;
-}
-
-/**
- * Equality comparison of 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @return 1 if operands are equal, 0 otherwise.
- */
-int eq128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
-{
-	return (a_hi == b_hi) && (a_lo == b_lo);
-}
-
-/**
- * Lower-or-equal comparison of 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @return 1 if a is lower or equal to b, 0 otherwise.
- */
-int le128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
-{
-	return (a_hi < b_hi) || ((a_hi == b_hi) && (a_lo <= b_lo));
-}
-
-/**
- * Lower-than comparison of 128-bit operands.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @return 1 if a is lower than b, 0 otherwise.
- */
-int lt128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo)
-{
-	return (a_hi < b_hi) || ((a_hi == b_hi) && (a_lo < b_lo));
-}
-
-/**
- * Addition of two 128-bit unsigned integers.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void add128(uint64_t a_hi, uint64_t a_lo,
-    uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	uint64_t low = a_lo + b_lo;
-	*r_lo = low;
-	/* detect overflow to add a carry */
-	*r_hi = a_hi + b_hi + (low < a_lo);
-}
-
-/**
- * Substraction of two 128-bit unsigned integers.
- *
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void sub128(uint64_t a_hi, uint64_t a_lo,
-    uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hi, uint64_t *r_lo)
-{
-	*r_lo = a_lo - b_lo;
-	/* detect underflow to substract a carry */
-	*r_hi = a_hi - b_hi - (a_lo < b_lo);
-}
-
-/**
- * Multiplication of two 64-bit unsigned integers.
- * 
- * @param a First input operand.
- * @param b Second input operand.
- * @param r_hi Address to store high part of the result.
- * @param r_lo Address to store low part of the result.
- */
-void mul64(uint64_t a, uint64_t b, uint64_t *r_hi, uint64_t *r_lo)
-{
-	uint64_t low, high, middle1, middle2;
-	uint32_t alow, blow;
-
-	alow = a & 0xFFFFFFFF;
-	blow = b & 0xFFFFFFFF;
-
-	a >>= 32;
-	b >>= 32;
-
-	low = ((uint64_t) alow) * blow;
-	middle1 = a * blow;
-	middle2 = alow * b;
-	high = a * b;
-
-	middle1 += middle2;
-	high += (((uint64_t) (middle1 < middle2)) << 32) + (middle1 >> 32);
-	middle1 <<= 32;
-	low += middle1;
-	high += (low < middle1);
-	*r_lo = low;
-	*r_hi = high;
-}
-
-/**
- * Multiplication of two 128-bit unsigned integers.
- * 
- * @param a_hi High part of the first input operand.
- * @param a_lo Low part of the first input operand.
- * @param b_hi High part of the second input operand.
- * @param b_lo Low part of the second input operand.
- * @param r_hihi Address to store first (highest) quarter of the result.
- * @param r_hilo Address to store second quarter of the result.
- * @param r_lohi Address to store third quarter of the result.
- * @param r_lolo Address to store fourth (lowest) quarter of the result.
- */
-void mul128(uint64_t a_hi, uint64_t a_lo, uint64_t b_hi, uint64_t b_lo,
-    uint64_t *r_hihi, uint64_t *r_hilo, uint64_t *r_lohi, uint64_t *r_lolo)
-{
-	uint64_t hihi, hilo, lohi, lolo;
-	uint64_t tmp1, tmp2;
-
-	mul64(a_lo, b_lo, &lohi, &lolo);
-	mul64(a_lo, b_hi, &hilo, &tmp2);
-	add128(hilo, tmp2, 0x0ll, lohi, &hilo, &lohi);
-	mul64(a_hi, b_hi, &hihi, &tmp1);
-	add128(hihi, tmp1, 0x0ll, hilo, &hihi, &hilo);
-	mul64(a_hi, b_lo, &tmp1, &tmp2);
-	add128(tmp1, tmp2, 0x0ll, lohi, &tmp1, &lohi);
-	add128(hihi, hilo, 0x0ll, tmp1, &hihi, &hilo);
-
-	*r_hihi = hihi;
-	*r_hilo = hilo;
-	*r_lohi = lohi;
-	*r_lolo = lolo;
-}
-
-/**
- * Estimate the quotient of 128-bit unsigned divident and 64-bit unsigned
- * divisor.
- * 
- * @param a_hi High part of the divident.
- * @param a_lo Low part of the divident.
- * @param b Divisor.
- * @return Quotient approximation.
- */
-uint64_t div128est(uint64_t a_hi, uint64_t a_lo, uint64_t b)
-{
-	uint64_t b_hi, b_lo;
-	uint64_t rem_hi, rem_lo;
-	uint64_t tmp_hi, tmp_lo;
-	uint64_t result;
-
-	if (b <= a_hi) {
-		return 0xFFFFFFFFFFFFFFFFull;
-	}
-
-	b_hi = b >> 32;
-	result = ((b_hi << 32) <= a_hi) ? (0xFFFFFFFFull << 32) : (a_hi / b_hi) << 32;
-	mul64(b, result, &tmp_hi, &tmp_lo);
-	sub128(a_hi, a_lo, tmp_hi, tmp_lo, &rem_hi, &rem_lo);
-	
-	while ((int64_t) rem_hi < 0) {
-		result -= 0x1ll << 32;
-		b_lo = b << 32;
-		add128(rem_hi, rem_lo, b_hi, b_lo, &rem_hi, &rem_lo);
-	}
-
-	rem_hi = (rem_hi << 32) | (rem_lo >> 32);
-	if ((b_hi << 32) <= rem_hi) {
-		result |= 0xFFFFFFFF;
-	} else {
-		result |= rem_hi / b_hi;
-	}
-
-	return result;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/comparison.c
===================================================================
--- uspace/lib/softfloat/generic/comparison.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,442 +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 Comparison functions.
- */
-
-#include <sftypes.h>
-#include <comparison.h>
-#include <common.h>
-
-/**
- * Determines whether the given float represents NaN (either signalling NaN or
- * quiet NaN).
- *
- * @param f Single-precision float.
- * @return 1 if float is NaN, 0 otherwise.
- */
-int is_float32_nan(float32 f)
-{
-	/* NaN : exp = 0xff and nonzero fraction */
-	return ((f.parts.exp == 0xFF) && (f.parts.fraction));
-}
-
-/**
- * Determines whether the given float represents NaN (either signalling NaN or
- * quiet NaN).
- *
- * @param d Double-precision float.
- * @return 1 if float is NaN, 0 otherwise.
- */
-int is_float64_nan(float64 d)
-{
-	/* NaN : exp = 0x7ff and nonzero fraction */
-	return ((d.parts.exp == 0x7FF) && (d.parts.fraction));
-}
-
-/**
- * Determines whether the given float represents NaN (either signalling NaN or
- * quiet NaN).
- *
- * @param ld Quadruple-precision float.
- * @return 1 if float is NaN, 0 otherwise.
- */
-int is_float128_nan(float128 ld)
-{
-	/* NaN : exp = 0x7fff and nonzero fraction */
-	return ((ld.parts.exp == 0x7FF) &&
-	    !eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
-}
-
-/**
- * Determines whether the given float represents signalling NaN.
- *
- * @param f Single-precision float.
- * @return 1 if float is signalling NaN, 0 otherwise.
- */
-int is_float32_signan(float32 f)
-{
-	/* SigNaN : exp = 0xff and fraction = 0xxxxx..x (binary),
-	 * where at least one x is nonzero */
-	return ((f.parts.exp == 0xFF) &&
-	    (f.parts.fraction < 0x400000) && (f.parts.fraction));
-}
-
-/**
- * Determines whether the given float represents signalling NaN.
- *
- * @param d Double-precision float.
- * @return 1 if float is signalling NaN, 0 otherwise.
- */
-int is_float64_signan(float64 d)
-{
-	/* SigNaN : exp = 0x7ff and fraction = 0xxxxx..x (binary),
-	 * where at least one x is nonzero */
-	return ((d.parts.exp == 0x7FF) &&
-	    (d.parts.fraction) && (d.parts.fraction < 0x8000000000000ll));
-}
-
-/**
- * Determines whether the given float represents signalling NaN.
- *
- * @param ld Quadruple-precision float.
- * @return 1 if float is signalling NaN, 0 otherwise.
- */
-int is_float128_signan(float128 ld)
-{
-	/* SigNaN : exp = 0x7fff and fraction = 0xxxxx..x (binary),
-	 * where at least one x is nonzero */
-	return ((ld.parts.exp == 0x7FFF) &&
-	    (ld.parts.frac_hi || ld.parts.frac_lo) &&
-	    lt128(ld.parts.frac_hi, ld.parts.frac_lo, 0x800000000000ll, 0x0ll));
-
-}
-
-/**
- * Determines whether the given float represents positive or negative infinity.
- *
- * @param f Single-precision float.
- * @return 1 if float is infinite, 0 otherwise.
- */
-int is_float32_infinity(float32 f)
-{
-	/* NaN : exp = 0x7ff and zero fraction */
-	return ((f.parts.exp == 0xFF) && (f.parts.fraction == 0x0));
-}
-
-/**
- * Determines whether the given float represents positive or negative infinity.
- *
- * @param d Double-precision float.
- * @return 1 if float is infinite, 0 otherwise.
- */
-int is_float64_infinity(float64 d)
-{
-	/* NaN : exp = 0x7ff and zero fraction */
-	return ((d.parts.exp == 0x7FF) && (d.parts.fraction == 0x0));
-}
-
-/**
- * Determines whether the given float represents positive or negative infinity.
- *
- * @param ld Quadruple-precision float.
- * @return 1 if float is infinite, 0 otherwise.
- */
-int is_float128_infinity(float128 ld)
-{
-	/* NaN : exp = 0x7fff and zero fraction */
-	return ((ld.parts.exp == 0x7FFF) &&
-	    eq128(ld.parts.frac_hi, ld.parts.frac_lo, 0x0ll, 0x0ll));
-}
-
-/**
- * Determines whether the given float represents positive or negative zero.
- *
- * @param f Single-precision float.
- * @return 1 if float is zero, 0 otherwise.
- */
-int is_float32_zero(float32 f)
-{
-	return (((f.bin) & 0x7FFFFFFF) == 0);
-}
-
-/**
- * Determines whether the given float represents positive or negative zero.
- *
- * @param d Double-precision float.
- * @return 1 if float is zero, 0 otherwise.
- */
-int is_float64_zero(float64 d)
-{
-	return (((d.bin) & 0x7FFFFFFFFFFFFFFFll) == 0);
-}
-
-/**
- * Determines whether the given float represents positive or negative zero.
- *
- * @param ld Quadruple-precision float.
- * @return 1 if float is zero, 0 otherwise.
- */
-int is_float128_zero(float128 ld)
-{
-	uint64_t tmp_hi;
-	uint64_t tmp_lo;
-	
-	and128(ld.bin.hi, ld.bin.lo,
-	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
-	
-	return eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
-}
-
-/**
- * Determine whether two floats are equal. NaNs are not recognized.
- *
- * @a First single-precision operand.
- * @b Second single-precision operand.
- * @return 1 if both floats are equal, 0 otherwise.
- */
-int is_float32_eq(float32 a, float32 b)
-{
-	/* a equals to b or both are zeros (with any sign) */
-	return ((a.bin == b.bin) ||
-	    (((a.bin | b.bin) & 0x7FFFFFFF) == 0));
-}
-
-/**
- * Determine whether two floats are equal. NaNs are not recognized.
- *
- * @a First double-precision operand.
- * @b Second double-precision operand.
- * @return 1 if both floats are equal, 0 otherwise.
- */
-int is_float64_eq(float64 a, float64 b)
-{
-	/* a equals to b or both are zeros (with any sign) */
-	return ((a.bin == b.bin) ||
-	    (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0));
-}
-
-/**
- * Determine whether two floats are equal. NaNs are not recognized.
- *
- * @a First quadruple-precision operand.
- * @b Second quadruple-precision operand.
- * @return 1 if both floats are equal, 0 otherwise.
- */
-int is_float128_eq(float128 a, float128 b)
-{
-	uint64_t tmp_hi;
-	uint64_t tmp_lo;
-	
-	/* both are zeros (with any sign) */
-	or128(a.bin.hi, a.bin.lo,
-	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
-	and128(tmp_hi, tmp_lo,
-	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
-	int both_zero = eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll);
-	
-	/* a equals to b */
-	int are_equal = eq128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
-	
-	return are_equal || both_zero;
-}
-
-/**
- * Lower-than comparison between two floats. NaNs are not recognized.
- *
- * @a First single-precision operand.
- * @b Second single-precision operand.
- * @return 1 if a is lower than b, 0 otherwise.
- */
-int is_float32_lt(float32 a, float32 b) 
-{
-	if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
-		/* +- zeroes */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, smaller is that with greater binary value */
-		return (a.bin > b.bin);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return (a.bin < b.bin);
-}
-
-/**
- * Lower-than comparison between two floats. NaNs are not recognized.
- *
- * @a First double-precision operand.
- * @b Second double-precision operand.
- * @return 1 if a is lower than b, 0 otherwise.
- */
-int is_float64_lt(float64 a, float64 b)
-{
-	if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
-		/* +- zeroes */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, smaller is that with greater binary value */
-		return (a.bin > b.bin);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return (a.bin < b.bin);
-}
-
-/**
- * Lower-than comparison between two floats. NaNs are not recognized.
- *
- * @a First quadruple-precision operand.
- * @b Second quadruple-precision operand.
- * @return 1 if a is lower than b, 0 otherwise.
- */
-int is_float128_lt(float128 a, float128 b)
-{
-	uint64_t tmp_hi;
-	uint64_t tmp_lo;
-	
-	or128(a.bin.hi, a.bin.lo,
-	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
-	and128(tmp_hi, tmp_lo,
-	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
-	if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
-		/* +- zeroes */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, smaller is that with greater binary value */
-		return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
-}
-
-/**
- * Greater-than comparison between two floats. NaNs are not recognized.
- *
- * @a First single-precision operand.
- * @b Second single-precision operand.
- * @return 1 if a is greater than b, 0 otherwise.
- */
-int is_float32_gt(float32 a, float32 b) 
-{
-	if (((a.bin | b.bin) & 0x7FFFFFFF) == 0) {
-		/* zeroes are equal with any sign */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, greater is that with smaller binary value */
-		return (a.bin < b.bin);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return (a.bin > b.bin);
-}
-
-/**
- * Greater-than comparison between two floats. NaNs are not recognized.
- *
- * @a First double-precision operand.
- * @b Second double-precision operand.
- * @return 1 if a is greater than b, 0 otherwise.
- */
-int is_float64_gt(float64 a, float64 b)
-{
-	if (((a.bin | b.bin) & 0x7FFFFFFFFFFFFFFFll) == 0) {
-		/* zeroes are equal with any sign */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, greater is that with smaller binary value */
-		return (a.bin < b.bin);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return (a.bin > b.bin);
-}
-
-/**
- * Greater-than comparison between two floats. NaNs are not recognized.
- *
- * @a First quadruple-precision operand.
- * @b Second quadruple-precision operand.
- * @return 1 if a is greater than b, 0 otherwise.
- */
-int is_float128_gt(float128 a, float128 b)
-{
-	uint64_t tmp_hi;
-	uint64_t tmp_lo;
-	
-	or128(a.bin.hi, a.bin.lo,
-	    b.bin.hi, b.bin.lo, &tmp_hi, &tmp_lo);
-	and128(tmp_hi, tmp_lo,
-	    0x7FFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, &tmp_hi, &tmp_lo);
-	if (eq128(tmp_hi, tmp_lo, 0x0ll, 0x0ll)) {
-		/* zeroes are equal with any sign */
-		return 0;
-	}
-	
-	if ((a.parts.sign) && (b.parts.sign)) {
-		/* if both are negative, greater is that with smaller binary value */
-		return lt128(a.bin.hi, a.bin.lo, b.bin.hi, b.bin.lo);
-	}
-	
-	/*
-	 * lets negate signs - now will be positive numbers always
-	 * bigger than negative (first bit will be set for unsigned
-	 * integer comparison)
-	 */
-	a.parts.sign = !a.parts.sign;
-	b.parts.sign = !b.parts.sign;
-	return lt128(b.bin.hi, b.bin.lo, a.bin.hi, a.bin.lo);
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/conversion.c
===================================================================
--- uspace/lib/softfloat/generic/conversion.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,1041 +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 Conversion of precision and conversion between integers and floats.
- */
-
-#include <sftypes.h>
-#include <conversion.h>
-#include <comparison.h>
-#include <common.h>
-
-float64 float32_to_float64(float32 a)
-{
-	float64 result;
-	uint64_t frac;
-	
-	result.parts.sign = a.parts.sign;
-	result.parts.fraction = a.parts.fraction;
-	result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
-	
-	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
-		result.parts.exp = FLOAT64_MAX_EXPONENT;
-		// TODO; check if its correct for SigNaNs
-		return result;
-	}
-	
-	result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
-	if (a.parts.exp == 0) {
-		/* normalize denormalized numbers */
-		
-		if (result.parts.fraction == 0) { /* fix zero */
-			result.parts.exp = 0;
-			return result;
-		}
-			
-		frac = result.parts.fraction;
-		
-		while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
-			frac <<= 1;
-			--result.parts.exp;
-		}
-		
-		++result.parts.exp;
-		result.parts.fraction = frac;
-	}
-	
-	return result;
-}
-
-float128 float32_to_float128(float32 a)
-{
-	float128 result;
-	uint64_t frac_hi, frac_lo;
-	uint64_t tmp_hi, tmp_lo;
-	
-	result.parts.sign = a.parts.sign;
-	result.parts.frac_hi = 0;
-	result.parts.frac_lo = a.parts.fraction;
-	lshift128(result.parts.frac_hi, result.parts.frac_lo,
-	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE),
-	    &frac_hi, &frac_lo);
-	result.parts.frac_hi = frac_hi;
-	result.parts.frac_lo = frac_lo;
-	
-	if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
-		result.parts.exp = FLOAT128_MAX_EXPONENT;
-		// TODO; check if its correct for SigNaNs
-		return result;
-	}
-	
-	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
-	if (a.parts.exp == 0) {
-		/* normalize denormalized numbers */
-		
-		if (eq128(result.parts.frac_hi,
-		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
-			result.parts.exp = 0;
-			return result;
-		}
-		
-		frac_hi = result.parts.frac_hi;
-		frac_lo = result.parts.frac_lo;
-		
-		and128(frac_hi, frac_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hi, &tmp_lo);
-		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
-			--result.parts.exp;
-		}
-		
-		++result.parts.exp;
-		result.parts.frac_hi = frac_hi;
-		result.parts.frac_lo = frac_lo;
-	}
-	
-	return result;
-}
-
-float128 float64_to_float128(float64 a)
-{
-	float128 result;
-	uint64_t frac_hi, frac_lo;
-	uint64_t tmp_hi, tmp_lo;
-	
-	result.parts.sign = a.parts.sign;
-	result.parts.frac_hi = 0;
-	result.parts.frac_lo = a.parts.fraction;
-	lshift128(result.parts.frac_hi, result.parts.frac_lo,
-	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE),
-	    &frac_hi, &frac_lo);
-	result.parts.frac_hi = frac_hi;
-	result.parts.frac_lo = frac_lo;
-	
-	if ((is_float64_infinity(a)) || (is_float64_nan(a))) {
-		result.parts.exp = FLOAT128_MAX_EXPONENT;
-		// TODO; check if its correct for SigNaNs
-		return result;
-	}
-	
-	result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
-	if (a.parts.exp == 0) {
-		/* normalize denormalized numbers */
-		
-		if (eq128(result.parts.frac_hi,
-		    result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
-			result.parts.exp = 0;
-			return result;
-		}
-		
-		frac_hi = result.parts.frac_hi;
-		frac_lo = result.parts.frac_lo;
-		
-		and128(frac_hi, frac_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hi, &tmp_lo);
-		while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-			lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
-			--result.parts.exp;
-		}
-		
-		++result.parts.exp;
-		result.parts.frac_hi = frac_hi;
-		result.parts.frac_lo = frac_lo;
-	}
-	
-	return result;
-}
-
-float32 float64_to_float32(float64 a)
-{
-	float32 result;
-	int32_t exp;
-	uint64_t frac;
-	
-	result.parts.sign = a.parts.sign;
-	
-	if (is_float64_nan(a)) {
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		
-		if (is_float64_signan(a)) {
-			/* set first bit of fraction nonzero */
-			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
-			return result;
-		}
-		
-		/* fraction nonzero but its first bit is zero */
-		result.parts.fraction = 0x1;
-		return result;
-	}
-	
-	if (is_float64_infinity(a)) {
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		return result;
-	}
-	
-	exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
-	
-	if (exp >= FLOAT32_MAX_EXPONENT) {
-		/* FIXME: overflow */
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		return result;
-	} else if (exp <= 0) {
-		/* underflow or denormalized */
-		
-		result.parts.exp = 0;
-		
-		exp *= -1;	
-		if (exp > FLOAT32_FRACTION_SIZE) {
-			/* FIXME: underflow */
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		/* denormalized */
-		
-		frac = a.parts.fraction; 
-		frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
-		
-		frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
-		
-		while (exp > 0) {
-			--exp;
-			frac >>= 1;
-		}
-		result.parts.fraction = frac;
-		
-		return result;
-	}
-	
-	result.parts.exp = exp;
-	result.parts.fraction =
-	    a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
-	return result;
-}
-
-float32 float128_to_float32(float128 a)
-{
-	float32 result;
-	int32_t exp;
-	uint64_t frac_hi, frac_lo;
-	
-	result.parts.sign = a.parts.sign;
-	
-	if (is_float128_nan(a)) {
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		
-		if (is_float128_signan(a)) {
-			/* set first bit of fraction nonzero */
-			result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
-			return result;
-		}
-		
-		/* fraction nonzero but its first bit is zero */
-		result.parts.fraction = 0x1;
-		return result;
-	}
-	
-	if (is_float128_infinity(a)) {
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		return result;
-	}
-	
-	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
-	
-	if (exp >= FLOAT32_MAX_EXPONENT) {
-		/* FIXME: overflow */
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		return result;
-	} else if (exp <= 0) {
-		/* underflow or denormalized */
-		
-		result.parts.exp = 0;
-		
-		exp *= -1;
-		if (exp > FLOAT32_FRACTION_SIZE) {
-			/* FIXME: underflow */
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		/* denormalized */
-		
-		frac_hi = a.parts.frac_hi;
-		frac_lo = a.parts.frac_lo;
-		
-		/* denormalize and set hidden bit */
-		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
-		
-		rshift128(frac_hi, frac_lo,
-		    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
-		    &frac_hi, &frac_lo);
-		
-		while (exp > 0) {
-			--exp;
-			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
-		}
-		result.parts.fraction = frac_lo;
-		
-		return result;
-	}
-	
-	result.parts.exp = exp;
-	frac_hi = a.parts.frac_hi;
-	frac_lo = a.parts.frac_lo;
-	rshift128(frac_hi, frac_lo,
-	    (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
-	    &frac_hi, &frac_lo);
-	result.parts.fraction = frac_lo;
-	return result;
-}
-
-float64 float128_to_float64(float128 a)
-{
-	float64 result;
-	int32_t exp;
-	uint64_t frac_hi, frac_lo;
-	
-	result.parts.sign = a.parts.sign;
-	
-	if (is_float128_nan(a)) {
-		result.parts.exp = FLOAT64_MAX_EXPONENT;
-		
-		if (is_float128_signan(a)) {
-			/* set first bit of fraction nonzero */
-			result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
-			return result;
-		}
-		
-		/* fraction nonzero but its first bit is zero */
-		result.parts.fraction = 0x1;
-		return result;
-	}
-	
-	if (is_float128_infinity(a)) {
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT64_MAX_EXPONENT;
-		return result;
-	}
-	
-	exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
-	
-	if (exp >= FLOAT64_MAX_EXPONENT) {
-		/* FIXME: overflow */
-		result.parts.fraction = 0;
-		result.parts.exp = FLOAT64_MAX_EXPONENT;
-		return result;
-	} else if (exp <= 0) {
-		/* underflow or denormalized */
-		
-		result.parts.exp = 0;
-		
-		exp *= -1;
-		if (exp > FLOAT64_FRACTION_SIZE) {
-			/* FIXME: underflow */
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		/* denormalized */
-		
-		frac_hi = a.parts.frac_hi;
-		frac_lo = a.parts.frac_lo;
-		
-		/* denormalize and set hidden bit */
-		frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
-		
-		rshift128(frac_hi, frac_lo,
-		    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
-		    &frac_hi, &frac_lo);
-		
-		while (exp > 0) {
-			--exp;
-			rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
-		}
-		result.parts.fraction = frac_lo;
-		
-		return result;
-	}
-	
-	result.parts.exp = exp;
-	frac_hi = a.parts.frac_hi;
-	frac_lo = a.parts.frac_lo;
-	rshift128(frac_hi, frac_lo,
-	    (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
-	    &frac_hi, &frac_lo);
-	result.parts.fraction = frac_lo;
-	return result;
-}
-
-/** Helper procedure for converting float32 to uint32.
- *
- * @param a Floating point number in normalized form
- *     (NaNs or Inf are not checked).
- * @return Converted unsigned integer.
- */
-static uint32_t _float32_to_uint32_helper(float32 a)
-{
-	uint32_t frac;
-	
-	if (a.parts.exp < FLOAT32_BIAS) {
-		/* TODO: rounding */
-		return 0;
-	}
-	
-	frac = a.parts.fraction;
-	
-	frac |= FLOAT32_HIDDEN_BIT_MASK;
-	/* shift fraction to left so hidden bit will be the most significant bit */
-	frac <<= 32 - FLOAT32_FRACTION_SIZE - 1; 
-	
-	frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
-	if ((a.parts.sign == 1) && (frac != 0)) {
-		frac = ~frac;
-		++frac;
-	}
-	
-	return frac;
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-uint32_t float32_to_uint32(float32 a)
-{
-	if (is_float32_nan(a))
-		return UINT32_MAX;
-	
-	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
-		if (a.parts.sign)
-			return UINT32_MIN;
-		
-		return UINT32_MAX;
-	}
-	
-	return _float32_to_uint32_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-int32_t float32_to_int32(float32 a)
-{
-	if (is_float32_nan(a))
-		return INT32_MAX;
-	
-	if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
-		if (a.parts.sign)
-			return INT32_MIN;
-		
-		return INT32_MAX;
-	}
-	
-	return _float32_to_uint32_helper(a);
-}
-
-/** Helper procedure for converting float32 to uint64.
- *
- * @param a Floating point number in normalized form
- *     (NaNs or Inf are not checked).
- * @return Converted unsigned integer.
- */
-static uint64_t _float32_to_uint64_helper(float32 a)
-{
-	uint64_t frac;
-	
-	if (a.parts.exp < FLOAT32_BIAS) {
-		// TODO: rounding
-		return 0;
-	}
-	
-	frac = a.parts.fraction;
-	
-	frac |= FLOAT32_HIDDEN_BIT_MASK;
-	/* shift fraction to left so hidden bit will be the most significant bit */
-	frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
-	
-	frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
-	if ((a.parts.sign == 1) && (frac != 0)) {
-		frac = ~frac;
-		++frac;
-	}
-	
-	return frac;
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-uint64_t float32_to_uint64(float32 a)
-{
-	if (is_float32_nan(a))
-		return UINT64_MAX;
-	
-	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
-		if (a.parts.sign)
-			return UINT64_MIN;
-		
-		return UINT64_MAX;
-	}
-	
-	return _float32_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-int64_t float32_to_int64(float32 a)
-{
-	if (is_float32_nan(a))
-		return INT64_MAX;
-	
-	if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
-		if (a.parts.sign)
-			return INT64_MIN;
-		
-		return INT64_MAX;
-	}
-	
-	return _float32_to_uint64_helper(a);
-}
-
-/** Helper procedure for converting float64 to uint64.
- *
- * @param a Floating point number in normalized form
- *     (NaNs or Inf are not checked).
- * @return Converted unsigned integer.
- */
-static uint64_t _float64_to_uint64_helper(float64 a)
-{
-	uint64_t frac;
-	
-	if (a.parts.exp < FLOAT64_BIAS) {
-		// TODO: rounding
-		return 0;
-	}
-	
-	frac = a.parts.fraction;
-	
-	frac |= FLOAT64_HIDDEN_BIT_MASK;
-	/* shift fraction to left so hidden bit will be the most significant bit */
-	frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
-	
-	frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
-	if ((a.parts.sign == 1) && (frac != 0)) {
-		frac = ~frac;
-		++frac;
-	}
-	
-	return frac;
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-uint32_t float64_to_uint32(float64 a)
-{
-	if (is_float64_nan(a))
-		return UINT32_MAX;
-	
-	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
-		if (a.parts.sign)
-			return UINT32_MIN;
-		
-		return UINT32_MAX;
-	}
-	
-	return (uint32_t) _float64_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-int32_t float64_to_int32(float64 a)
-{
-	if (is_float64_nan(a))
-		return INT32_MAX;
-	
-	if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
-		if (a.parts.sign)
-			return INT32_MIN;
-		
-		return INT32_MAX;
-	}
-	
-	return (int32_t) _float64_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens 
- *  - now its the biggest or the smallest int
- */
-uint64_t float64_to_uint64(float64 a)
-{
-	if (is_float64_nan(a))
-		return UINT64_MAX;
-	
-	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
-		if (a.parts.sign)
-			return UINT64_MIN;
-		
-		return UINT64_MAX;
-	}
-	
-	return _float64_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens 
- *  - now its the biggest or the smallest int
- */
-int64_t float64_to_int64(float64 a)
-{
-	if (is_float64_nan(a))
-		return INT64_MAX;
-	
-	if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
-		if (a.parts.sign)
-			return INT64_MIN;
-		
-		return INT64_MAX;
-	}
-	
-	return _float64_to_uint64_helper(a);
-}
-
-/** Helper procedure for converting float128 to uint64.
- *
- * @param a Floating point number in normalized form
- *     (NaNs or Inf are not checked).
- * @return Converted unsigned integer.
- */
-static uint64_t _float128_to_uint64_helper(float128 a)
-{
-	uint64_t frac_hi, frac_lo;
-	
-	if (a.parts.exp < FLOAT128_BIAS) {
-		// TODO: rounding
-		return 0;
-	}
-	
-	frac_hi = a.parts.frac_hi;
-	frac_lo = a.parts.frac_lo;
-	
-	frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
-	/* shift fraction to left so hidden bit will be the most significant bit */
-	lshift128(frac_hi, frac_lo,
-	    (128 - FLOAT128_FRACTION_SIZE - 1), &frac_hi, &frac_lo);
-	
-	rshift128(frac_hi, frac_lo,
-	    (128 - (a.parts.exp - FLOAT128_BIAS) - 1), &frac_hi, &frac_lo);
-	if ((a.parts.sign == 1) && !eq128(frac_hi, frac_lo, 0x0ll, 0x0ll)) {
-		not128(frac_hi, frac_lo, &frac_hi, &frac_lo);
-		add128(frac_hi, frac_lo, 0x0ll, 0x1ll, &frac_hi, &frac_lo);
-	}
-	
-	return frac_lo;
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-uint32_t float128_to_uint32(float128 a)
-{
-	if (is_float128_nan(a))
-		return UINT32_MAX;
-	
-	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
-		if (a.parts.sign)
-			return UINT32_MIN;
-		
-		return UINT32_MAX;
-	}
-	
-	return (uint32_t) _float128_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-int32_t float128_to_int32(float128 a)
-{
-	if (is_float128_nan(a))
-		return INT32_MAX;
-	
-	if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
-		if (a.parts.sign)
-			return INT32_MIN;
-		
-		return INT32_MAX;
-	}
-	
-	return (int32_t) _float128_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-uint64_t float128_to_uint64(float128 a)
-{
-	if (is_float128_nan(a))
-		return UINT64_MAX;
-	
-	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
-		if (a.parts.sign)
-			return UINT64_MIN;
-		
-		return UINT64_MAX;
-	}
-	
-	return _float128_to_uint64_helper(a);
-}
-
-/*
- * FIXME: Im not sure what to return if overflow/underflow happens
- *  - now its the biggest or the smallest int
- */
-int64_t float128_to_int64(float128 a)
-{
-	if (is_float128_nan(a))
-		return INT64_MAX;
-	
-	if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
-		if (a.parts.sign)
-			return INT64_MIN;
-		
-		return INT64_MAX;
-	}
-	
-	return _float128_to_uint64_helper(a);
-}
-
-float32 uint32_to_float32(uint32_t i)
-{
-	int counter;
-	int32_t exp;
-	float32 result;
-	
-	result.parts.sign = 0;
-	result.parts.fraction = 0;
-	
-	counter = count_zeroes32(i);
-	
-	exp = FLOAT32_BIAS + 32 - counter - 1;
-	
-	if (counter == 32) {
-		result.bin = 0;
-		return result;
-	}
-	
-	if (counter > 0) {
-		i <<= counter - 1;
-	} else {
-		i >>= 1;
-	}
-	
-	round_float32(&exp, &i);
-	
-	result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
-	result.parts.exp = exp;
-	
-	return result;
-}
-
-float32 int32_to_float32(int32_t i)
-{
-	float32 result;
-	
-	if (i < 0)
-		result = uint32_to_float32((uint32_t) (-i));
-	else
-		result = uint32_to_float32((uint32_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-float32 uint64_to_float32(uint64_t i)
-{
-	int counter;
-	int32_t exp;
-	uint32_t j;
-	float32 result;
-	
-	result.parts.sign = 0;
-	result.parts.fraction = 0;
-	
-	counter = count_zeroes64(i);
-	
-	exp = FLOAT32_BIAS + 64 - counter - 1;
-	
-	if (counter == 64) {
-		result.bin = 0;
-		return result;
-	}
-	
-	/* Shift all to the first 31 bits (31st will be hidden 1) */
-	if (counter > 33) {
-		i <<= counter - 1 - 32;
-	} else {
-		i >>= 1 + 32 - counter;
-	}
-	
-	j = (uint32_t) i;
-	round_float32(&exp, &j);
-	
-	result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
-	result.parts.exp = exp;
-	return result;
-}
-
-float32 int64_to_float32(int64_t i)
-{
-	float32 result;
-	
-	if (i < 0)
-		result = uint64_to_float32((uint64_t) (-i));
-	else
-		result = uint64_to_float32((uint64_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-float64 uint32_to_float64(uint32_t i)
-{
-	int counter;
-	int32_t exp;
-	float64 result;
-	uint64_t frac;
-	
-	result.parts.sign = 0;
-	result.parts.fraction = 0;
-	
-	counter = count_zeroes32(i);
-	
-	exp = FLOAT64_BIAS + 32 - counter - 1;
-	
-	if (counter == 32) {
-		result.bin = 0;
-		return result;
-	}
-	
-	frac = i;
-	frac <<= counter + 32 - 1;
-	
-	round_float64(&exp, &frac);
-	
-	result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
-	result.parts.exp = exp;
-	
-	return result;
-}
-
-float64 int32_to_float64(int32_t i)
-{
-	float64 result;
-	
-	if (i < 0)
-		result = uint32_to_float64((uint32_t) (-i));
-	else
-		result = uint32_to_float64((uint32_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-
-float64 uint64_to_float64(uint64_t i)
-{
-	int counter;
-	int32_t exp;
-	float64 result;
-	
-	result.parts.sign = 0;
-	result.parts.fraction = 0;
-	
-	counter = count_zeroes64(i);
-	
-	exp = FLOAT64_BIAS + 64 - counter - 1;
-	
-	if (counter == 64) {
-		result.bin = 0;
-		return result;
-	}
-	
-	if (counter > 0) {
-		i <<= counter - 1;
-	} else {
-		i >>= 1;
-	}
-	
-	round_float64(&exp, &i);
-	
-	result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
-	result.parts.exp = exp;
-	return result;
-}
-
-float64 int64_to_float64(int64_t i)
-{
-	float64 result;
-	
-	if (i < 0)
-		result = uint64_to_float64((uint64_t) (-i));
-	else
-		result = uint64_to_float64((uint64_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-float128 uint32_to_float128(uint32_t i)
-{
-	int counter;
-	int32_t exp;
-	float128 result;
-	uint64_t frac_hi, frac_lo;
-	
-	result.parts.sign = 0;
-	result.parts.frac_hi = 0;
-	result.parts.frac_lo = 0;
-	
-	counter = count_zeroes32(i);
-	
-	exp = FLOAT128_BIAS + 32 - counter - 1;
-	
-	if (counter == 32) {
-		result.bin.hi = 0;
-		result.bin.lo = 0;
-		return result;
-	}
-	
-	frac_hi = 0;
-	frac_lo = i;
-	lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
-	
-	round_float128(&exp, &frac_hi, &frac_lo);
-	
-	rshift128(frac_hi, frac_lo,
-	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
-	result.parts.frac_hi = frac_hi;
-	result.parts.frac_lo = frac_lo;
-	result.parts.exp = exp;
-	
-	return result;
-}
-
-float128 int32_to_float128(int32_t i)
-{
-	float128 result;
-	
-	if (i < 0)
-		result = uint32_to_float128((uint32_t) (-i));
-	else
-		result = uint32_to_float128((uint32_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-
-float128 uint64_to_float128(uint64_t i)
-{
-	int counter;
-	int32_t exp;
-	float128 result;
-	uint64_t frac_hi, frac_lo;
-	
-	result.parts.sign = 0;
-	result.parts.frac_hi = 0;
-	result.parts.frac_lo = 0;
-	
-	counter = count_zeroes64(i);
-	
-	exp = FLOAT128_BIAS + 64 - counter - 1;
-	
-	if (counter == 64) {
-		result.bin.hi = 0;
-		result.bin.lo = 0;
-		return result;
-	}
-	
-	frac_hi = 0;
-	frac_lo = i;
-	lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
-	
-	round_float128(&exp, &frac_hi, &frac_lo);
-	
-	rshift128(frac_hi, frac_lo,
-	    (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
-	result.parts.frac_hi = frac_hi;
-	result.parts.frac_lo = frac_lo;
-	result.parts.exp = exp;
-	
-	return result;
-}
-
-float128 int64_to_float128(int64_t i)
-{
-	float128 result;
-	
-	if (i < 0)
-		result = uint64_to_float128((uint64_t) (-i));
-	else
-		result = uint64_to_float128((uint64_t) i);
-	
-	result.parts.sign = i < 0;
-	
-	return result;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/div.c
===================================================================
--- uspace/lib/softfloat/generic/div.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,542 +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 Division functions.
- */
-
-#include <sftypes.h>
-#include <add.h>
-#include <div.h>
-#include <comparison.h>
-#include <mul.h>
-#include <common.h>
-
-/** Divide two single-precision floats.
- *
- * @param a Nominator.
- * @param b Denominator.
- *
- * @return Result of division.
- *
- */
-float32 div_float32(float32 a, float32 b)
-{
-	float32 result;
-	int32_t aexp, bexp, cexp;
-	uint64_t afrac, bfrac, cfrac;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float32_nan(a)) {
-		if (is_float32_signan(a)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return a;
-	}
-	
-	if (is_float32_nan(b)) {
-		if (is_float32_signan(b)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return b;
-	}
-	
-	if (is_float32_infinity(a)) {
-		if (is_float32_infinity(b)) {
-			/*FIXME: inf / inf */
-			result.bin = FLOAT32_NAN;
-			return result;
-		}
-		/* inf / num */
-		result.parts.exp = a.parts.exp;
-		result.parts.fraction = a.parts.fraction;
-		return result;
-	}
-	
-	if (is_float32_infinity(b)) {
-		if (is_float32_zero(a)) {
-			/* FIXME 0 / inf */
-			result.parts.exp = 0;
-			result.parts.fraction = 0;
-			return result;
-		}
-		/* FIXME: num / inf*/
-		result.parts.exp = 0;
-		result.parts.fraction = 0;
-		return result;
-	}
-	
-	if (is_float32_zero(b)) {
-		if (is_float32_zero(a)) {
-			/*FIXME: 0 / 0*/
-			result.bin = FLOAT32_NAN;
-			return result;
-		}
-		/* FIXME: division by zero */
-		result.parts.exp = 0;
-		result.parts.fraction = 0;
-		return result;
-	}
-	
-	afrac = a.parts.fraction;
-	aexp = a.parts.exp;
-	bfrac = b.parts.fraction;
-	bexp = b.parts.exp;
-	
-	/* denormalized numbers */
-	if (aexp == 0) {
-		if (afrac == 0) {
-			result.parts.exp = 0;
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		/* normalize it*/
-		afrac <<= 1;
-		/* afrac is nonzero => it must stop */
-		while (!(afrac & FLOAT32_HIDDEN_BIT_MASK)) {
-			afrac <<= 1;
-			aexp--;
-		}
-	}
-	
-	if (bexp == 0) {
-		bfrac <<= 1;
-		/* bfrac is nonzero => it must stop */
-		while (!(bfrac & FLOAT32_HIDDEN_BIT_MASK)) {
-			bfrac <<= 1;
-			bexp--;
-		}
-	}
-	
-	afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK) << (32 - FLOAT32_FRACTION_SIZE - 1);
-	bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK) << (32 - FLOAT32_FRACTION_SIZE);
-	
-	if (bfrac <= (afrac << 1)) {
-		afrac >>= 1;
-		aexp++;
-	}
-	
-	cexp = aexp - bexp + FLOAT32_BIAS - 2;
-	
-	cfrac = (afrac << 32) / bfrac;
-	if ((cfrac & 0x3F) == 0) { 
-		cfrac |= (bfrac * cfrac != afrac << 32);
-	}
-	
-	/* pack and round */
-	
-	/* find first nonzero digit and shift result and detect possibly underflow */
-	while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)))) {
-		cexp--;
-		cfrac <<= 1;
-		/* TODO: fix underflow */
-	}
-	
-	cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
-	
-	if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
-		++cexp;
-		cfrac >>= 1;
-	}
-	
-	/* check overflow */
-	if (cexp >= FLOAT32_MAX_EXPONENT) {
-		/* FIXME: overflow, return infinity */
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		result.parts.fraction = 0;
-		return result;
-	}
-	
-	if (cexp < 0) {
-		/* FIXME: underflow */
-		result.parts.exp = 0;
-		if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
-			result.parts.fraction = 0;
-			return result;
-		}
-		cfrac >>= 1;
-		while (cexp < 0) {
-			cexp++;
-			cfrac >>= 1;
-		}
-	} else {
-		result.parts.exp = (uint32_t) cexp;
-	}
-	
-	result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
-	
-	return result;
-}
-
-/** Divide two double-precision floats.
- *
- * @param a Nominator.
- * @param b Denominator.
- *
- * @return Result of division.
- *
- */
-float64 div_float64(float64 a, float64 b) 
-{
-	float64 result;
-	int64_t aexp, bexp, cexp;
-	uint64_t afrac, bfrac, cfrac; 
-	uint64_t remlo, remhi;
-	uint64_t tmplo, tmphi;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float64_nan(a)) {
-		if (is_float64_signan(b)) {
-			// FIXME: SigNaN
-			return b;
-		}
-		
-		if (is_float64_signan(a)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return a;
-	}
-	
-	if (is_float64_nan(b)) {
-		if (is_float64_signan(b)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return b;
-	}
-	
-	if (is_float64_infinity(a)) {
-		if (is_float64_infinity(b) || is_float64_zero(b)) {
-			// FIXME: inf / inf
-			result.bin = FLOAT64_NAN;
-			return result;
-		}
-		/* inf / num */
-		result.parts.exp = a.parts.exp;
-		result.parts.fraction = a.parts.fraction;
-		return result;
-	}
-	
-	if (is_float64_infinity(b)) {
-		if (is_float64_zero(a)) {
-			/* FIXME 0 / inf */
-			result.parts.exp = 0;
-			result.parts.fraction = 0;
-			return result;
-		}
-		/* FIXME: num / inf*/
-		result.parts.exp = 0;
-		result.parts.fraction = 0;
-		return result;
-	}
-	
-	if (is_float64_zero(b)) {
-		if (is_float64_zero(a)) {
-			/*FIXME: 0 / 0*/
-			result.bin = FLOAT64_NAN;
-			return result;
-		}
-		/* FIXME: division by zero */
-		result.parts.exp = 0;
-		result.parts.fraction = 0;
-		return result;
-	}
-	
-	afrac = a.parts.fraction;
-	aexp = a.parts.exp;
-	bfrac = b.parts.fraction;
-	bexp = b.parts.exp;
-	
-	/* denormalized numbers */
-	if (aexp == 0) {
-		if (afrac == 0) {
-			result.parts.exp = 0;
-			result.parts.fraction = 0;
-			return result;
-		}
-		
-		/* normalize it*/
-		aexp++;
-		/* afrac is nonzero => it must stop */	
-		while (!(afrac & FLOAT64_HIDDEN_BIT_MASK)) {
-			afrac <<= 1;
-			aexp--;
-		}
-	}
-	
-	if (bexp == 0) {
-		bexp++;
-		/* bfrac is nonzero => it must stop */	
-		while (!(bfrac & FLOAT64_HIDDEN_BIT_MASK)) {
-			bfrac <<= 1;
-			bexp--;
-		}
-	}
-	
-	afrac = (afrac | FLOAT64_HIDDEN_BIT_MASK) << (64 - FLOAT64_FRACTION_SIZE - 2);
-	bfrac = (bfrac | FLOAT64_HIDDEN_BIT_MASK) << (64 - FLOAT64_FRACTION_SIZE - 1);
-	
-	if (bfrac <= (afrac << 1)) {
-		afrac >>= 1;
-		aexp++;
-	}
-	
-	cexp = aexp - bexp + FLOAT64_BIAS - 2; 
-	
-	cfrac = div128est(afrac, 0x0ll, bfrac);
-	
-	if ((cfrac & 0x1FF) <= 2) {
-		mul64(bfrac, cfrac, &tmphi, &tmplo);
-		sub128(afrac, 0x0ll, tmphi, tmplo, &remhi, &remlo);
-		
-		while ((int64_t) remhi < 0) {
-			cfrac--;
-			add128(remhi, remlo, 0x0ll, bfrac, &remhi, &remlo);
-		}
-		cfrac |= (remlo != 0);
-	}
-	
-	/* round and shift */
-	result = finish_float64(cexp, cfrac, result.parts.sign);
-	return result;
-}
-
-/** Divide two quadruple-precision floats.
- *
- * @param a Nominator.
- * @param b Denominator.
- *
- * @return Result of division.
- *
- */
-float128 div_float128(float128 a, float128 b)
-{
-	float128 result;
-	int64_t aexp, bexp, cexp;
-	uint64_t afrac_hi, afrac_lo, bfrac_hi, bfrac_lo, cfrac_hi, cfrac_lo;
-	uint64_t shift_out;
-	uint64_t rem_hihi, rem_hilo, rem_lohi, rem_lolo;
-	uint64_t tmp_hihi, tmp_hilo, tmp_lohi, tmp_lolo;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float128_nan(a)) {
-		if (is_float128_signan(b)) {
-			// FIXME: SigNaN
-			return b;
-		}
-		
-		if (is_float128_signan(a)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return a;
-	}
-	
-	if (is_float128_nan(b)) {
-		if (is_float128_signan(b)) {
-			// FIXME: SigNaN
-		}
-		/* NaN */
-		return b;
-	}
-	
-	if (is_float128_infinity(a)) {
-		if (is_float128_infinity(b) || is_float128_zero(b)) {
-			// FIXME: inf / inf
-			result.bin.hi = FLOAT128_NAN_HI;
-			result.bin.lo = FLOAT128_NAN_LO;
-			return result;
-		}
-		/* inf / num */
-		result.parts.exp = a.parts.exp;
-		result.parts.frac_hi = a.parts.frac_hi;
-		result.parts.frac_lo = a.parts.frac_lo;
-		return result;
-	}
-	
-	if (is_float128_infinity(b)) {
-		if (is_float128_zero(a)) {
-			// FIXME 0 / inf
-			result.parts.exp = 0;
-			result.parts.frac_hi = 0;
-			result.parts.frac_lo = 0;
-			return result;
-		}
-		// FIXME: num / inf
-		result.parts.exp = 0;
-		result.parts.frac_hi = 0;
-		result.parts.frac_lo = 0;
-		return result;
-	}
-	
-	if (is_float128_zero(b)) {
-		if (is_float128_zero(a)) {
-			// FIXME: 0 / 0
-			result.bin.hi = FLOAT128_NAN_HI;
-			result.bin.lo = FLOAT128_NAN_LO;
-			return result;
-		}
-		// FIXME: division by zero
-		result.parts.exp = 0;
-		result.parts.frac_hi = 0;
-		result.parts.frac_lo = 0;
-		return result;
-	}
-	
-	afrac_hi = a.parts.frac_hi;
-	afrac_lo = a.parts.frac_lo;
-	aexp = a.parts.exp;
-	bfrac_hi = b.parts.frac_hi;
-	bfrac_lo = b.parts.frac_lo;
-	bexp = b.parts.exp;
-	
-	/* denormalized numbers */
-	if (aexp == 0) {
-		if (eq128(afrac_hi, afrac_lo, 0x0ll, 0x0ll)) {
-			result.parts.exp = 0;
-			result.parts.frac_hi = 0;
-			result.parts.frac_lo = 0;
-			return result;
-		}
-		
-		/* normalize it*/
-		aexp++;
-		/* afrac is nonzero => it must stop */
-		and128(afrac_hi, afrac_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hihi, &tmp_lolo);
-		while (!lt128(0x0ll, 0x0ll, tmp_hihi, tmp_lolo)) {
-			lshift128(afrac_hi, afrac_lo, 1, &afrac_hi, &afrac_lo);
-			aexp--;
-		}
-	}
-	
-	if (bexp == 0) {
-		bexp++;
-		/* bfrac is nonzero => it must stop */
-		and128(bfrac_hi, bfrac_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &tmp_hihi, &tmp_lolo);
-		while (!lt128(0x0ll, 0x0ll, tmp_hihi, tmp_lolo)) {
-			lshift128(bfrac_hi, bfrac_lo, 1, &bfrac_hi, &bfrac_lo);
-			bexp--;
-		}
-	}
-	
-	or128(afrac_hi, afrac_lo,
-	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &afrac_hi, &afrac_lo);
-	lshift128(afrac_hi, afrac_lo,
-	    (128 - FLOAT128_FRACTION_SIZE - 1), &afrac_hi, &afrac_lo);
-	or128(bfrac_hi, bfrac_lo,
-	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &bfrac_hi, &bfrac_lo);
-	lshift128(bfrac_hi, bfrac_lo,
-	    (128 - FLOAT128_FRACTION_SIZE - 1), &bfrac_hi, &bfrac_lo);
-	
-	if (le128(bfrac_hi, bfrac_lo, afrac_hi, afrac_lo)) {
-		rshift128(afrac_hi, afrac_lo, 1, &afrac_hi, &afrac_lo);
-		aexp++;
-	}
-	
-	cexp = aexp - bexp + FLOAT128_BIAS - 2;
-	
-	cfrac_hi = div128est(afrac_hi, afrac_lo, bfrac_hi);
-	
-	mul128(bfrac_hi, bfrac_lo, 0x0ll, cfrac_hi,
-	    &tmp_lolo /* dummy */, &tmp_hihi, &tmp_hilo, &tmp_lohi);
-	
-	/* sub192(afrac_hi, afrac_lo, 0,
-	 *     tmp_hihi, tmp_hilo, tmp_lohi
-	 *     &rem_hihi, &rem_hilo, &rem_lohi); */
-	sub128(afrac_hi, afrac_lo, tmp_hihi, tmp_hilo, &rem_hihi, &rem_hilo);
-	if (tmp_lohi > 0) {
-		sub128(rem_hihi, rem_hilo, 0x0ll, 0x1ll, &rem_hihi, &rem_hilo);
-	}
-	rem_lohi = -tmp_lohi;
-	
-	while ((int64_t) rem_hihi < 0) {
-		--cfrac_hi;
-		/* add192(rem_hihi, rem_hilo, rem_lohi,
-		 *     0, bfrac_hi, bfrac_lo,
-		 *     &rem_hihi, &rem_hilo, &rem_lohi); */
-		add128(rem_hilo, rem_lohi, bfrac_hi, bfrac_lo, &rem_hilo, &rem_lohi);
-		if (lt128(rem_hilo, rem_lohi, bfrac_hi, bfrac_lo)) {
-			++rem_hihi;
-		}
-	}
-	
-	cfrac_lo = div128est(rem_hilo, rem_lohi, bfrac_lo);
-	
-	if ((cfrac_lo & 0x3FFF) <= 4) {
-		mul128(bfrac_hi, bfrac_lo, 0x0ll, cfrac_lo,
-		    &tmp_hihi /* dummy */, &tmp_hilo, &tmp_lohi, &tmp_lolo);
-		
-		/* sub192(rem_hilo, rem_lohi, 0,
-		 *     tmp_hilo, tmp_lohi, tmp_lolo,
-		 *     &rem_hilo, &rem_lohi, &rem_lolo); */
-		sub128(rem_hilo, rem_lohi, tmp_hilo, tmp_lohi, &rem_hilo, &rem_lohi);
-		if (tmp_lolo > 0) {
-			sub128(rem_hilo, rem_lohi, 0x0ll, 0x1ll, &rem_hilo, &rem_lohi);
-		}
-		rem_lolo = -tmp_lolo;
-		
-		while ((int64_t) rem_hilo < 0) {
-			--cfrac_lo;
-			/* add192(rem_hilo, rem_lohi, rem_lolo,
-			 *     0, bfrac_hi, bfrac_lo,
-			 *     &rem_hilo, &rem_lohi, &rem_lolo); */
-			add128(rem_lohi, rem_lolo, bfrac_hi, bfrac_lo, &rem_lohi, &rem_lolo);
-			if (lt128(rem_lohi, rem_lolo, bfrac_hi, bfrac_lo)) {
-				++rem_hilo;
-			}
-		}
-		
-		cfrac_lo |= ((rem_hilo | rem_lohi | rem_lolo) != 0 );
-	}
-	
-	shift_out = cfrac_lo << (64 - (128 - FLOAT128_FRACTION_SIZE - 1));
-	rshift128(cfrac_hi, cfrac_lo, (128 - FLOAT128_FRACTION_SIZE - 1),
-	    &cfrac_hi, &cfrac_lo);
-	
-	result = finish_float128(cexp, cfrac_hi, cfrac_lo, result.parts.sign, shift_out);
-	return result;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/mul.c
===================================================================
--- uspace/lib/softfloat/generic/mul.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,383 +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 Multiplication functions.
- */
-
-#include <sftypes.h>
-#include <mul.h>
-#include <comparison.h>
-#include <common.h>
-
-/** Multiply two single-precision floats.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of multiplication.
- *
- */
-float32 mul_float32(float32 a, float32 b)
-{
-	float32 result;
-	uint64_t frac1, frac2;
-	int32_t exp;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float32_nan(a) || is_float32_nan(b)) {
-		/* TODO: fix SigNaNs */
-		if (is_float32_signan(a)) {
-			result.parts.fraction = a.parts.fraction;
-			result.parts.exp = a.parts.exp;
-			return result;
-		}
-		if (is_float32_signan(b)) { /* TODO: fix SigNaN */
-			result.parts.fraction = b.parts.fraction;
-			result.parts.exp = b.parts.exp;
-			return result;
-		}
-		/* set NaN as result */
-		result.bin = FLOAT32_NAN;
-		return result;
-	}
-	
-	if (is_float32_infinity(a)) {
-		if (is_float32_zero(b)) {
-			/* FIXME: zero * infinity */
-			result.bin = FLOAT32_NAN;
-			return result;
-		}
-		result.parts.fraction = a.parts.fraction;
-		result.parts.exp = a.parts.exp;
-		return result;
-	}
-	
-	if (is_float32_infinity(b)) {
-		if (is_float32_zero(a)) {
-			/* FIXME: zero * infinity */
-			result.bin = FLOAT32_NAN;
-			return result;
-		}
-		result.parts.fraction = b.parts.fraction;
-		result.parts.exp = b.parts.exp;
-		return result;
-	}
-	
-	/* exp is signed so we can easy detect underflow */
-	exp = a.parts.exp + b.parts.exp;
-	exp -= FLOAT32_BIAS;
-	
-	if (exp >= FLOAT32_MAX_EXPONENT) {
-		/* FIXME: overflow */
-		/* set infinity as result */
-		result.bin = FLOAT32_INF;
-		result.parts.sign = a.parts.sign ^ b.parts.sign;
-		return result;
-	}
-	
-	if (exp < 0) { 
-		/* FIXME: underflow */
-		/* return signed zero */
-		result.parts.fraction = 0x0;
-		result.parts.exp = 0x0;
-		return result;
-	}
-	
-	frac1 = a.parts.fraction;
-	if (a.parts.exp > 0) {
-		frac1 |= FLOAT32_HIDDEN_BIT_MASK;
-	} else {
-		++exp;
-	}
-	
-	frac2 = b.parts.fraction;
-	
-	if (b.parts.exp > 0) {
-		frac2 |= FLOAT32_HIDDEN_BIT_MASK;
-	} else {
-		++exp;
-	}
-	
-	frac1 <<= 1; /* one bit space for rounding */
-	
-	frac1 = frac1 * frac2;
-	
-	/* round and return */
-	while ((exp < FLOAT32_MAX_EXPONENT) &&
-	    (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 2)))) {
-		/* 23 bits of fraction + one more for hidden bit (all shifted 1 bit left) */
-		++exp;
-		frac1 >>= 1;
-	}
-	
-	/* rounding */
-	/* ++frac1; FIXME: not works - without it is ok */
-	frac1 >>= 1; /* shift off rounding space */
-	
-	if ((exp < FLOAT32_MAX_EXPONENT) &&
-	    (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 1)))) {
-		++exp;
-		frac1 >>= 1;
-	}
-	
-	if (exp >= FLOAT32_MAX_EXPONENT) {
-		/* TODO: fix overflow */
-		/* return infinity*/
-		result.parts.exp = FLOAT32_MAX_EXPONENT;
-		result.parts.fraction = 0x0;
-		return result;
-	}
-	
-	exp -= FLOAT32_FRACTION_SIZE;
-	
-	if (exp <= FLOAT32_FRACTION_SIZE) {
-		/* denormalized number */
-		frac1 >>= 1; /* denormalize */
-		while ((frac1 > 0) && (exp < 0)) {
-			frac1 >>= 1;
-			++exp;
-		}
-		if (frac1 == 0) {
-			/* FIXME : underflow */
-			result.parts.exp = 0;
-			result.parts.fraction = 0;
-			return result;
-		}
-	}
-	result.parts.exp = exp; 
-	result.parts.fraction = frac1 & ((1 << FLOAT32_FRACTION_SIZE) - 1);
-	
-	return result;
-}
-
-/** Multiply two double-precision floats.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of multiplication.
- *
- */
-float64 mul_float64(float64 a, float64 b)
-{
-	float64 result;
-	uint64_t frac1, frac2;
-	int32_t exp;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float64_nan(a) || is_float64_nan(b)) {
-		/* TODO: fix SigNaNs */
-		if (is_float64_signan(a)) {
-			result.parts.fraction = a.parts.fraction;
-			result.parts.exp = a.parts.exp;
-			return result;
-		}
-		if (is_float64_signan(b)) { /* TODO: fix SigNaN */
-			result.parts.fraction = b.parts.fraction;
-			result.parts.exp = b.parts.exp;
-			return result;
-		}
-		/* set NaN as result */
-		result.bin = FLOAT64_NAN;
-		return result;
-	}
-	
-	if (is_float64_infinity(a)) {
-		if (is_float64_zero(b)) {
-			/* FIXME: zero * infinity */
-			result.bin = FLOAT64_NAN;
-			return result;
-		}
-		result.parts.fraction = a.parts.fraction;
-		result.parts.exp = a.parts.exp;
-		return result;
-	}
-	
-	if (is_float64_infinity(b)) {
-		if (is_float64_zero(a)) {
-			/* FIXME: zero * infinity */
-			result.bin = FLOAT64_NAN;
-			return result;
-		}
-		result.parts.fraction = b.parts.fraction;
-		result.parts.exp = b.parts.exp;
-		return result;
-	}
-	
-	/* exp is signed so we can easy detect underflow */
-	exp = a.parts.exp + b.parts.exp - FLOAT64_BIAS;
-	
-	frac1 = a.parts.fraction;
-	
-	if (a.parts.exp > 0) {
-		frac1 |= FLOAT64_HIDDEN_BIT_MASK;
-	} else {
-		++exp;
-	}
-	
-	frac2 = b.parts.fraction;
-	
-	if (b.parts.exp > 0) {
-		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
-	} else {
-		++exp;
-	}
-	
-	frac1 <<= (64 - FLOAT64_FRACTION_SIZE - 1);
-	frac2 <<= (64 - FLOAT64_FRACTION_SIZE - 2);
-	
-	mul64(frac1, frac2, &frac1, &frac2);
-	
-	frac1 |= (frac2 != 0);
-	if (frac1 & (0x1ll << 62)) {
-		frac1 <<= 1;
-		exp--;
-	}
-	
-	result = finish_float64(exp, frac1, result.parts.sign);
-	return result;
-}
-
-/** Multiply two quadruple-precision floats.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of multiplication.
- *
- */
-float128 mul_float128(float128 a, float128 b)
-{
-	float128 result;
-	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
-	int32_t exp;
-	
-	result.parts.sign = a.parts.sign ^ b.parts.sign;
-	
-	if (is_float128_nan(a) || is_float128_nan(b)) {
-		/* TODO: fix SigNaNs */
-		if (is_float128_signan(a)) {
-			result.parts.frac_hi = a.parts.frac_hi;
-			result.parts.frac_lo = a.parts.frac_lo;
-			result.parts.exp = a.parts.exp;
-			return result;
-		}
-		if (is_float128_signan(b)) { /* TODO: fix SigNaN */
-			result.parts.frac_hi = b.parts.frac_hi;
-			result.parts.frac_lo = b.parts.frac_lo;
-			result.parts.exp = b.parts.exp;
-			return result;
-		}
-		/* set NaN as result */
-		result.bin.hi = FLOAT128_NAN_HI;
-		result.bin.lo = FLOAT128_NAN_LO;
-		return result;
-	}
-	
-	if (is_float128_infinity(a)) {
-		if (is_float128_zero(b)) {
-			/* FIXME: zero * infinity */
-			result.bin.hi = FLOAT128_NAN_HI;
-			result.bin.lo = FLOAT128_NAN_LO;
-			return result;
-		}
-		result.parts.frac_hi = a.parts.frac_hi;
-		result.parts.frac_lo = a.parts.frac_lo;
-		result.parts.exp = a.parts.exp;
-		return result;
-	}
-	
-	if (is_float128_infinity(b)) {
-		if (is_float128_zero(a)) {
-			/* FIXME: zero * infinity */
-			result.bin.hi = FLOAT128_NAN_HI;
-			result.bin.lo = FLOAT128_NAN_LO;
-			return result;
-		}
-		result.parts.frac_hi = b.parts.frac_hi;
-		result.parts.frac_lo = b.parts.frac_lo;
-		result.parts.exp = b.parts.exp;
-		return result;
-	}
-	
-	/* exp is signed so we can easy detect underflow */
-	exp = a.parts.exp + b.parts.exp - FLOAT128_BIAS - 1;
-	
-	frac1_hi = a.parts.frac_hi;
-	frac1_lo = a.parts.frac_lo;
-	
-	if (a.parts.exp > 0) {
-		or128(frac1_hi, frac1_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &frac1_hi, &frac1_lo);
-	} else {
-		++exp;
-	}
-	
-	frac2_hi = b.parts.frac_hi;
-	frac2_lo = b.parts.frac_lo;
-	
-	if (b.parts.exp > 0) {
-		or128(frac2_hi, frac2_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &frac2_hi, &frac2_lo);
-	} else {
-		++exp;
-	}
-	
-	lshift128(frac2_hi, frac2_lo,
-	    128 - FLOAT128_FRACTION_SIZE, &frac2_hi, &frac2_lo);
-	
-	tmp_hi = frac1_hi;
-	tmp_lo = frac1_lo;
-	mul128(frac1_hi, frac1_lo, frac2_hi, frac2_lo,
-	    &frac1_hi, &frac1_lo, &frac2_hi, &frac2_lo);
-	add128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo);
-	frac2_hi |= (frac2_lo != 0x0ll);
-	
-	if ((FLOAT128_HIDDEN_BIT_MASK_HI << 1) <= frac1_hi) {
-		frac2_hi >>= 1;
-		if (frac1_lo & 0x1ll) {
-			frac2_hi |= (0x1ull < 64);
-		}
-		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
-		++exp;
-	}
-	
-	result = finish_float128(exp, frac1_hi, frac1_lo, result.parts.sign, frac2_hi);
-	return result;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/generic/other.c
===================================================================
--- uspace/lib/softfloat/generic/other.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/*
- * Copyright (c) 2005 Josef Cejka
- * 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 Other functions (power, complex).
- */
-
-
-/** @}
- */
Index: pace/lib/softfloat/generic/softfloat.c
===================================================================
--- uspace/lib/softfloat/generic/softfloat.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,1325 +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>
-#include <other.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);
-}
-
-double __aeabi_i2d(int i)
-{
-	return __floatsidf(i);
-}
-
-double __aeabi_ui2d(unsigned int i)
-{
-	return __floatunsidf(i);
-}
-
-int __aeabi_d2iz(double a)
-{
-	return __fixdfsi(a);
-}
-
-unsigned int __aeabi_d2uiz(double a)
-{
-	return __fixunsdfsi(a);
-}
-
-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);
-}
-
-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/generic/sub.c
===================================================================
--- uspace/lib/softfloat/generic/sub.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,441 +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 Substraction functions.
- */
-
-#include <sftypes.h>
-#include <sub.h>
-#include <comparison.h>
-#include <common.h>
-
-/** Subtract two single-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of substraction.
- *
- */
-float32 sub_float32(float32 a, float32 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2, frac1, frac2;
-	float32 result;
-	
-	result.bin = 0;
-	
-	expdiff = a.parts.exp - b.parts.exp;
-	if ((expdiff < 0 ) || ((expdiff == 0) &&
-	    (a.parts.fraction < b.parts.fraction))) {
-		if (is_float32_nan(b)) {
-			if (is_float32_signan(b)) {
-				// TODO: fix SigNaN
-			}
-			
-			return b;
-		}
-		
-		if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
-			/* num -(+-inf) = -+inf */
-			b.parts.sign = !b.parts.sign;
-			return b;
-		}
-		
-		result.parts.sign = !a.parts.sign;
-		
-		frac1 = b.parts.fraction;
-		exp1 = b.parts.exp;
-		frac2 = a.parts.fraction;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if (is_float32_nan(a)) {
-			if ((is_float32_signan(a)) || (is_float32_signan(b))) {
-				// TODO: fix SigNaN
-			}
-			
-			return a;
-		}
-		
-		if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
-			if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
-				/* inf - inf => nan */
-				// TODO: fix exception
-				result.bin = FLOAT32_NAN;
-				return result;
-			}
-			
-			return a;
-		}
-		
-		result.parts.sign = a.parts.sign;
-		
-		frac1 = a.parts.fraction;
-		exp1 = a.parts.exp;
-		frac2 = b.parts.fraction;
-		exp2 = b.parts.exp;
-	}
-	
-	if (exp1 == 0) {
-		/* both are denormalized */
-		result.parts.fraction = frac1 - frac2;
-		if (result.parts.fraction > frac1) {
-			// TODO: underflow exception
-			return result;
-		}
-		
-		result.parts.exp = 0;
-		return result;
-	}
-	
-	/* add hidden bit */
-	frac1 |= FLOAT32_HIDDEN_BIT_MASK;
-	
-	if (exp2 == 0) {
-		/* denormalized */
-		--expdiff;
-	} else {
-		/* normalized */
-		frac2 |= FLOAT32_HIDDEN_BIT_MASK;
-	}
-	
-	/* create some space for rounding */
-	frac1 <<= 6;
-	frac2 <<= 6;
-	
-	if (expdiff > FLOAT32_FRACTION_SIZE + 1)
-		goto done;
-	
-	frac1 = frac1 - (frac2 >> expdiff);
-	
-done:
-	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
-	while ((exp1 > 0) && (!(frac1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) {
-		--exp1;
-		frac1 <<= 1;
-		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
-	}
-	
-	/* rounding - if first bit after fraction is set then round up */
-	frac1 += 0x20;
-	
-	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	/* Clear hidden bit and shift */
-	result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
-	result.parts.exp = exp1;
-	
-	return result;
-}
-
-/** Subtract two double-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of substraction.
- *
- */
-float64 sub_float64(float64 a, float64 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2;
-	uint64_t frac1, frac2;
-	float64 result;
-	
-	result.bin = 0;
-	
-	expdiff = a.parts.exp - b.parts.exp;
-	if ((expdiff < 0 ) ||
-	    ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
-		if (is_float64_nan(b)) {
-			if (is_float64_signan(b)) {
-				// TODO: fix SigNaN
-			}
-			
-			return b;
-		}
-		
-		if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
-			/* num -(+-inf) = -+inf */
-			b.parts.sign = !b.parts.sign;
-			return b;
-		}
-		
-		result.parts.sign = !a.parts.sign;
-		
-		frac1 = b.parts.fraction;
-		exp1 = b.parts.exp;
-		frac2 = a.parts.fraction;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if (is_float64_nan(a)) {
-			if (is_float64_signan(a) || is_float64_signan(b)) {
-				// TODO: fix SigNaN
-			}
-			
-			return a;
-		}
-		
-		if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
-			if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
-				/* inf - inf => nan */
-				// TODO: fix exception
-				result.bin = FLOAT64_NAN;
-				return result;
-			}
-			
-			return a;
-		}
-		
-		result.parts.sign = a.parts.sign;
-		
-		frac1 = a.parts.fraction;
-		exp1 = a.parts.exp;
-		frac2 = b.parts.fraction;
-		exp2 = b.parts.exp;
-	}
-	
-	if (exp1 == 0) {
-		/* both are denormalized */
-		result.parts.fraction = frac1 - frac2;
-		if (result.parts.fraction > frac1) {
-			// TODO: underflow exception
-			return result;
-		}
-		
-		result.parts.exp = 0;
-		return result;
-	}
-	
-	/* add hidden bit */
-	frac1 |= FLOAT64_HIDDEN_BIT_MASK;
-	
-	if (exp2 == 0) {
-		/* denormalized */
-		--expdiff;
-	} else {
-		/* normalized */
-		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
-	}
-	
-	/* create some space for rounding */
-	frac1 <<= 6;
-	frac2 <<= 6;
-	
-	if (expdiff > FLOAT64_FRACTION_SIZE + 1)
-		goto done;
-	
-	frac1 = frac1 - (frac2 >> expdiff);
-	
-done:
-	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
-	while ((exp1 > 0) && (!(frac1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) {
-		--exp1;
-		frac1 <<= 1;
-		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
-	}
-	
-	/* rounding - if first bit after fraction is set then round up */
-	frac1 += 0x20;
-	
-	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
-		++exp1;
-		frac1 >>= 1;
-	}
-	
-	/* Clear hidden bit and shift */
-	result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
-	result.parts.exp = exp1;
-	
-	return result;
-}
-
-/** Subtract two quadruple-precision floats with the same sign.
- *
- * @param a First input operand.
- * @param b Second input operand.
- *
- * @return Result of substraction.
- *
- */
-float128 sub_float128(float128 a, float128 b)
-{
-	int expdiff;
-	uint32_t exp1, exp2;
-	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
-	float128 result;
-	
-	result.bin.hi = 0;
-	result.bin.lo = 0;
-	
-	expdiff = a.parts.exp - b.parts.exp;
-	if ((expdiff < 0 ) || ((expdiff == 0) &&
-	    lt128(a.parts.frac_hi, a.parts.frac_lo, b.parts.frac_hi, b.parts.frac_lo))) {
-		if (is_float128_nan(b)) {
-			if (is_float128_signan(b)) {
-				// TODO: fix SigNaN
-			}
-			
-			return b;
-		}
-		
-		if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
-			/* num -(+-inf) = -+inf */
-			b.parts.sign = !b.parts.sign;
-			return b;
-		}
-		
-		result.parts.sign = !a.parts.sign;
-		
-		frac1_hi = b.parts.frac_hi;
-		frac1_lo = b.parts.frac_lo;
-		exp1 = b.parts.exp;
-		frac2_hi = a.parts.frac_hi;
-		frac2_lo = a.parts.frac_lo;
-		exp2 = a.parts.exp;
-		expdiff *= -1;
-	} else {
-		if (is_float128_nan(a)) {
-			if (is_float128_signan(a) || is_float128_signan(b)) {
-				// TODO: fix SigNaN
-			}
-			
-			return a;
-		}
-		
-		if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
-			if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
-				/* inf - inf => nan */
-				// TODO: fix exception
-				result.bin.hi = FLOAT128_NAN_HI;
-				result.bin.lo = FLOAT128_NAN_LO;
-				return result;
-			}
-			return a;
-		}
-		
-		result.parts.sign = a.parts.sign;
-		
-		frac1_hi = a.parts.frac_hi;
-		frac1_lo = a.parts.frac_lo;
-		exp1 = a.parts.exp;
-		frac2_hi = b.parts.frac_hi;
-		frac2_lo = b.parts.frac_lo;
-		exp2 = b.parts.exp;
-	}
-	
-	if (exp1 == 0) {
-		/* both are denormalized */
-		sub128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &tmp_hi, &tmp_lo);
-		result.parts.frac_hi = tmp_hi;
-		result.parts.frac_lo = tmp_lo;
-		if (lt128(frac1_hi, frac1_lo, result.parts.frac_hi, result.parts.frac_lo)) {
-			// TODO: underflow exception
-			return result;
-		}
-		
-		result.parts.exp = 0;
-		return result;
-	}
-	
-	/* add hidden bit */
-	or128(frac1_hi, frac1_lo,
-	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &frac1_hi, &frac1_lo);
-	
-	if (exp2 == 0) {
-		/* denormalized */
-		--expdiff;
-	} else {
-		/* normalized */
-		or128(frac2_hi, frac2_lo,
-		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-		    &frac2_hi, &frac2_lo);
-	}
-	
-	/* create some space for rounding */
-	lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
-	lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
-	
-	if (expdiff > FLOAT128_FRACTION_SIZE + 1)
-		goto done;
-	
-	rshift128(frac2_hi, frac2_lo, expdiff, &tmp_hi, &tmp_lo);
-	sub128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo);
-	
-done:
-	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6,
-	    &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	while ((exp1 > 0) && (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo))) {
-		--exp1;
-		lshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
-		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
-		
-		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6,
-		    &tmp_hi, &tmp_lo);
-		and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	}
-	
-	/* rounding - if first bit after fraction is set then round up */
-	add128(frac1_hi, frac1_lo, 0x0ll, 0x20ll, &frac1_hi, &frac1_lo);
-	
-	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
-	   &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
-		++exp1;
-		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
-	}
-	
-	/* Clear hidden bit and shift */
-	rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
-	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
-	    &tmp_hi, &tmp_lo);
-	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
-	result.parts.frac_hi = tmp_hi;
-	result.parts.frac_lo = tmp_lo;
-	
-	result.parts.exp = exp1;
-	
-	return result;
-}
-
-/** @}
- */
Index: pace/lib/softfloat/include/add.h
===================================================================
--- uspace/lib/softfloat/include/add.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,47 +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 Addition functions.
- */
-
-#ifndef __ADD_H__
-#define __ADD_H__
-
-extern float32 add_float32(float32, float32);
-extern float64 add_float64(float64, float64);
-extern float96 add_float96(float96, float96);
-extern float128 add_float128(float128, float128);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/common.h
===================================================================
--- uspace/lib/softfloat/include/common.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,76 +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 Common helper operations.
- */
-
-#ifndef __COMMON_H__
-#define __COMMON_H__
-
-#include <sftypes.h>
-
-extern float64 finish_float64(int32_t, uint64_t, char);
-extern float128 finish_float128(int32_t, uint64_t, uint64_t, char, uint64_t);
-
-extern int count_zeroes8(uint8_t);
-extern int count_zeroes32(uint32_t);
-extern int count_zeroes64(uint64_t);
-
-extern void round_float32(int32_t *, uint32_t *);
-extern void round_float64(int32_t *, uint64_t *);
-extern void round_float128(int32_t *, uint64_t *, uint64_t *);
-
-extern void lshift128(uint64_t, uint64_t, int, uint64_t *, uint64_t *);
-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 not128(uint64_t, uint64_t, uint64_t *, uint64_t *);
-
-extern int eq128(uint64_t, uint64_t, uint64_t, uint64_t);
-extern int le128(uint64_t, uint64_t, uint64_t, uint64_t);
-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 mul64(uint64_t, uint64_t, uint64_t *, uint64_t *);
-extern void mul128(uint64_t, uint64_t, uint64_t, uint64_t,
-    uint64_t *, uint64_t *, uint64_t *, uint64_t *);
-
-extern uint64_t div128est(uint64_t, uint64_t, uint64_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/comparison.h
===================================================================
--- uspace/lib/softfloat/include/comparison.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,82 +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 Comparison functions.
- */
-
-#ifndef __COMPARISON_H__
-#define __COMPARISON_H__
-
-extern int is_float32_nan(float32);
-extern int is_float32_signan(float32);
-
-extern int is_float32_infinity(float32);
-extern int is_float32_zero(float32);
-
-extern int is_float32_eq(float32, float32);
-extern int is_float32_lt(float32, float32);
-extern int is_float32_gt(float32, float32);
-
-extern int is_float64_nan(float64);
-extern int is_float64_signan(float64);
-
-extern int is_float64_infinity(float64);
-extern int is_float64_zero(float64);
-
-extern int is_float64_eq(float64, float64);
-extern int is_float64_lt(float64, float64);
-extern int is_float64_gt(float64, float64);
-
-extern int is_float96_nan(float96);
-extern int is_float96_signan(float96);
-
-extern int is_float96_infinity(float96);
-extern int is_float96_zero(float96);
-
-extern int is_float96_eq(float96, float96);
-extern int is_float96_lt(float96, float96);
-extern int is_float96_gt(float96, float96);
-
-extern int is_float128_nan(float128);
-extern int is_float128_signan(float128);
-
-extern int is_float128_infinity(float128);
-extern int is_float128_zero(float128);
-
-extern int is_float128_eq(float128, float128);
-extern int is_float128_lt(float128, float128);
-extern int is_float128_gt(float128, float128);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/conversion.h
===================================================================
--- uspace/lib/softfloat/include/conversion.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,104 +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 Conversion of precision and conversion between integers and floats.
- */
-
-#ifndef __CONVERSION_H__
-#define __CONVERSION_H__
-
-extern float64 float32_to_float64(float32);
-extern float96 float32_to_float96(float32);
-extern float128 float32_to_float128(float32);
-extern float96 float64_to_float96(float64);
-extern float128 float64_to_float128(float64);
-extern float128 float96_to_float128(float96);
-
-extern float32 float64_to_float32(float64);
-extern float32 float96_to_float32(float96);
-extern float64 float96_to_float64(float96);
-extern float32 float128_to_float32(float128);
-extern float64 float128_to_float64(float128);
-extern float96 float128_to_float96(float128);
-
-extern uint32_t float32_to_uint32(float32);
-extern int32_t float32_to_int32(float32);
-
-extern uint64_t float32_to_uint64(float32);
-extern int64_t float32_to_int64(float32);
-
-extern uint32_t float64_to_uint32(float64);
-extern int32_t float64_to_int32(float64);
-
-extern uint64_t float64_to_uint64(float64);
-extern int64_t float64_to_int64(float64);
-
-extern uint32_t float96_to_uint32(float96);
-extern int32_t float96_to_int32(float96);
-
-extern uint64_t float96_to_uint64(float96);
-extern int64_t float96_to_int64(float96);
-
-extern uint32_t float128_to_uint32(float128);
-extern int32_t float128_to_int32(float128);
-
-extern uint64_t float128_to_uint64(float128);
-extern int64_t float128_to_int64(float128);
-
-extern float32 uint32_to_float32(uint32_t);
-extern float32 int32_to_float32(int32_t);
-
-extern float32 uint64_to_float32(uint64_t);
-extern float32 int64_to_float32(int64_t);
-
-extern float64 uint32_to_float64(uint32_t);
-extern float64 int32_to_float64(int32_t);
-
-extern float64 uint64_to_float64(uint64_t);
-extern float64 int64_to_float64(int64_t);
-
-extern float96 uint32_to_float96(uint32_t);
-extern float96 int32_to_float96(int32_t);
-
-extern float96 uint64_to_float96(uint64_t);
-extern float96 int64_to_float96(int64_t);
-
-extern float128 uint32_to_float128(uint32_t);
-extern float128 int32_to_float128(int32_t);
-
-extern float128 uint64_to_float128(uint64_t);
-extern float128 int64_to_float128(int64_t);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/div.h
===================================================================
--- uspace/lib/softfloat/include/div.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,47 +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 Division functions.
- */
-
-#ifndef __DIV_H__
-#define __DIV_H__
-
-extern float32 div_float32(float32, float32);
-extern float64 div_float64(float64, float64);
-extern float96 div_float96(float96, float96);
-extern float128 div_float128(float128, float128);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/mul.h
===================================================================
--- uspace/lib/softfloat/include/mul.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,47 +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 Multiplication functions.
- */
-
-#ifndef __MUL_H__
-#define __MUL_H__
-
-extern float32 mul_float32(float32, float32);
-extern float64 mul_float64(float64, float64);
-extern float96 mul_float96(float96, float96);
-extern float128 mul_float128(float128, float128);
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/other.h
===================================================================
--- uspace/lib/softfloat/include/other.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2005 Josef Cejka
- * 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 Other functions (power, complex).
- */
-
-#ifndef __OTHER_H__
-#define __OTHER_H__
-
-#endif
-
-/** @}
- */
Index: pace/lib/softfloat/include/sftypes.h
===================================================================
--- uspace/lib/softfloat/include/sftypes.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,608 +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 __SFTYPES_H__
-#define __SFTYPES_H__
-
-#include <byteorder.h>
-#include <stdint.h>
-
-/*
- * For recognizing NaNs or infinity use specialized comparison
- * functions, comparing with these constants is not sufficient.
- */
-
-#define FLOAT32_NAN     UINT32_C(0x7FC00001)
-#define FLOAT32_SIGNAN  UINT32_C(0x7F800001)
-#define FLOAT32_INF     UINT32_C(0x7F800000)
-
-#define FLOAT64_NAN     UINT64_C(0x7FF8000000000001)
-#define FLOAT64_SIGNAN  UINT64_C(0x7FF0000000000001)
-#define FLOAT64_INF     UINT64_C(0x7FF0000000000000)
-
-#define FLOAT96_NAN_HI     UINT64_C(0x7FFF80000000)
-#define FLOAT96_NAN_LO     UINT32_C(0x00010000)
-#define FLOAT96_SIGNAN_HI  UINT64_C(0x7FFF00000000)
-#define FLOAT96_SIGNAN_LO  UINT32_C(0x00010000)
-
-#define FLOAT128_NAN_HI     UINT64_C(0x7FFF800000000000)
-#define FLOAT128_NAN_LO     UINT64_C(0x0000000000000001)
-#define FLOAT128_SIGNAN_HI  UINT64_C(0x7FFF000000000000)
-#define FLOAT128_SIGNAN_LO  UINT64_C(0x0000000000000001)
-#define FLOAT128_INF_HI     UINT64_C(0x7FFF000000000000)
-#define FLOAT128_INF_LO     UINT64_C(0x0000000000000000)
-
-#define FLOAT32_FRACTION_SIZE   23
-#define FLOAT64_FRACTION_SIZE   52
-#define FLOAT96_FRACTION_SIZE   64
-#define FLOAT128_FRACTION_SIZE  112
-#define FLOAT128_FRAC_HI_SIZE   48
-#define FLOAT128_FRAC_LO_SIZE   64
-
-#define FLOAT32_HIDDEN_BIT_MASK      UINT32_C(0x800000)
-#define FLOAT64_HIDDEN_BIT_MASK      UINT64_C(0x10000000000000)
-#define FLOAT128_HIDDEN_BIT_MASK_HI  UINT64_C(0x1000000000000)
-#define FLOAT128_HIDDEN_BIT_MASK_LO  UINT64_C(0x0000000000000000)
-
-#define FLOAT32_MAX_EXPONENT   0xFF
-#define FLOAT64_MAX_EXPONENT   0x7FF
-#define FLOAT96_MAX_EXPONENT   0x7FFF
-#define FLOAT128_MAX_EXPONENT  0x7FFF
-
-#define FLOAT32_BIAS   0x7F
-#define FLOAT64_BIAS   0x3FF
-#define FLOAT96_BIAS   0x3FFF
-#define FLOAT128_BIAS  0x3FFF
-
-#if defined(__BE__)
-
-typedef union {
-	uint32_t bin;
-	
-	struct {
-		uint32_t sign : 1;
-		uint32_t exp : 8;
-		uint32_t fraction : 23;
-	} parts __attribute__((packed));
-} float32;
-
-typedef union {
-	uint64_t bin;
-	
-	struct {
-		uint64_t sign : 1;
-		uint64_t exp : 11;
-		uint64_t fraction : 52;
-	} parts __attribute__((packed));
-} float64;
-
-typedef union {
-	struct {
-		uint64_t hi;
-		uint32_t lo;
-	} bin __attribute__((packed));
-	
-	struct {
-		uint64_t padding : 16;
-		uint64_t sign : 1;
-		uint64_t exp : 15;
-		uint64_t fraction : 64;
-	} parts __attribute__((packed));
-} float96;
-
-typedef union {
-	struct {
-		uint64_t hi;
-		uint64_t lo;
-	} bin __attribute__((packed));
-	
-	struct {
-		uint64_t sign : 1;
-		uint64_t exp : 15;
-		uint64_t frac_hi : 48;
-		uint64_t frac_lo : 64;
-	} parts __attribute__((packed));
-} float128;
-
-#elif defined(__LE__)
-
-typedef union {
-	uint32_t bin;
-	
-	struct {
-		uint32_t fraction : 23;
-		uint32_t exp : 8;
-		uint32_t sign : 1;
-	} parts __attribute__((packed));
-} float32;
-
-typedef union {
-	uint64_t bin;
-	
-	struct {
-		uint64_t fraction : 52;
-		uint64_t exp : 11;
-		uint64_t sign : 1;
-	} parts __attribute__((packed));
-} float64;
-
-typedef union {
-	struct {
-		uint32_t lo;
-		uint64_t hi;
-	} bin __attribute__((packed));
-	
-	struct {
-		uint64_t fraction : 64;
-		uint64_t exp : 15;
-		uint64_t sign : 1;
-		uint64_t padding : 16;
-	} parts __attribute__((packed));
-} float96;
-
-typedef union {
-	struct {
-		uint64_t lo;
-		uint64_t hi;
-	} bin __attribute__((packed));
-	
-	struct {
-		uint64_t frac_lo : 64;
-		uint64_t frac_hi : 48;
-		uint64_t exp : 15;
-		uint64_t sign : 1;
-	} parts __attribute__((packed));
-} float128;
-
-#else
-	#error Unknown endianess
-#endif
-
-typedef union {
-	float val;
-	
-#if defined(FLOAT_SIZE_32)
-	float32 data;
-#elif defined(FLOAT_SIZE_64)
-	float64 data;
-#elif defined(FLOAT_SIZE_96)
-	float96 data;
-#elif defined(FLOAT_SIZE_128)
-	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;
-
-
-#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/include/softfloat.h
===================================================================
--- uspace/lib/softfloat/include/softfloat.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,226 +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 double __aeabi_i2d(int);
-extern double __aeabi_ui2d(unsigned int);
-extern unsigned int __aeabi_d2uiz(double);
-extern int __aeabi_d2iz(double);
-
-extern int __aeabi_dcmpge(double, double);
-extern int __aeabi_dcmpgt(double, double);
-extern int __aeabi_dcmplt(double, double);
-
-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: pace/lib/softfloat/include/sub.h
===================================================================
--- uspace/lib/softfloat/include/sub.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ 	(revision )
@@ -1,47 +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 Substraction functions.
- */
-
-#ifndef __SUB_H__
-#define __SUB_H__
-
-extern float32 sub_float32(float32, float32);
-extern float64 sub_float64(float64, float64);
-extern float96 sub_float96(float96, float96);
-extern float128 sub_float128(float128, float128);
-
-#endif
-
-/** @}
- */
Index: uspace/lib/softfloat/mul.c
===================================================================
--- uspace/lib/softfloat/mul.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/mul.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,383 @@
+/*
+ * 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 Multiplication functions.
+ */
+
+#include "sftypes.h"
+#include "mul.h"
+#include "comparison.h"
+#include "common.h"
+
+/** Multiply two single-precision floats.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of multiplication.
+ *
+ */
+float32 mul_float32(float32 a, float32 b)
+{
+	float32 result;
+	uint64_t frac1, frac2;
+	int32_t exp;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float32_nan(a) || is_float32_nan(b)) {
+		/* TODO: fix SigNaNs */
+		if (is_float32_signan(a)) {
+			result.parts.fraction = a.parts.fraction;
+			result.parts.exp = a.parts.exp;
+			return result;
+		}
+		if (is_float32_signan(b)) { /* TODO: fix SigNaN */
+			result.parts.fraction = b.parts.fraction;
+			result.parts.exp = b.parts.exp;
+			return result;
+		}
+		/* set NaN as result */
+		result.bin = FLOAT32_NAN;
+		return result;
+	}
+	
+	if (is_float32_infinity(a)) {
+		if (is_float32_zero(b)) {
+			/* FIXME: zero * infinity */
+			result.bin = FLOAT32_NAN;
+			return result;
+		}
+		result.parts.fraction = a.parts.fraction;
+		result.parts.exp = a.parts.exp;
+		return result;
+	}
+	
+	if (is_float32_infinity(b)) {
+		if (is_float32_zero(a)) {
+			/* FIXME: zero * infinity */
+			result.bin = FLOAT32_NAN;
+			return result;
+		}
+		result.parts.fraction = b.parts.fraction;
+		result.parts.exp = b.parts.exp;
+		return result;
+	}
+	
+	/* exp is signed so we can easy detect underflow */
+	exp = a.parts.exp + b.parts.exp;
+	exp -= FLOAT32_BIAS;
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* FIXME: overflow */
+		/* set infinity as result */
+		result.bin = FLOAT32_INF;
+		result.parts.sign = a.parts.sign ^ b.parts.sign;
+		return result;
+	}
+	
+	if (exp < 0) { 
+		/* FIXME: underflow */
+		/* return signed zero */
+		result.parts.fraction = 0x0;
+		result.parts.exp = 0x0;
+		return result;
+	}
+	
+	frac1 = a.parts.fraction;
+	if (a.parts.exp > 0) {
+		frac1 |= FLOAT32_HIDDEN_BIT_MASK;
+	} else {
+		++exp;
+	}
+	
+	frac2 = b.parts.fraction;
+	
+	if (b.parts.exp > 0) {
+		frac2 |= FLOAT32_HIDDEN_BIT_MASK;
+	} else {
+		++exp;
+	}
+	
+	frac1 <<= 1; /* one bit space for rounding */
+	
+	frac1 = frac1 * frac2;
+	
+	/* round and return */
+	while ((exp < FLOAT32_MAX_EXPONENT) &&
+	    (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 2)))) {
+		/* 23 bits of fraction + one more for hidden bit (all shifted 1 bit left) */
+		++exp;
+		frac1 >>= 1;
+	}
+	
+	/* rounding */
+	/* ++frac1; FIXME: not works - without it is ok */
+	frac1 >>= 1; /* shift off rounding space */
+	
+	if ((exp < FLOAT32_MAX_EXPONENT) &&
+	    (frac1 >= (1 << (FLOAT32_FRACTION_SIZE + 1)))) {
+		++exp;
+		frac1 >>= 1;
+	}
+	
+	if (exp >= FLOAT32_MAX_EXPONENT) {
+		/* TODO: fix overflow */
+		/* return infinity*/
+		result.parts.exp = FLOAT32_MAX_EXPONENT;
+		result.parts.fraction = 0x0;
+		return result;
+	}
+	
+	exp -= FLOAT32_FRACTION_SIZE;
+	
+	if (exp <= FLOAT32_FRACTION_SIZE) {
+		/* denormalized number */
+		frac1 >>= 1; /* denormalize */
+		while ((frac1 > 0) && (exp < 0)) {
+			frac1 >>= 1;
+			++exp;
+		}
+		if (frac1 == 0) {
+			/* FIXME : underflow */
+			result.parts.exp = 0;
+			result.parts.fraction = 0;
+			return result;
+		}
+	}
+	result.parts.exp = exp; 
+	result.parts.fraction = frac1 & ((1 << FLOAT32_FRACTION_SIZE) - 1);
+	
+	return result;
+}
+
+/** Multiply two double-precision floats.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of multiplication.
+ *
+ */
+float64 mul_float64(float64 a, float64 b)
+{
+	float64 result;
+	uint64_t frac1, frac2;
+	int32_t exp;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float64_nan(a) || is_float64_nan(b)) {
+		/* TODO: fix SigNaNs */
+		if (is_float64_signan(a)) {
+			result.parts.fraction = a.parts.fraction;
+			result.parts.exp = a.parts.exp;
+			return result;
+		}
+		if (is_float64_signan(b)) { /* TODO: fix SigNaN */
+			result.parts.fraction = b.parts.fraction;
+			result.parts.exp = b.parts.exp;
+			return result;
+		}
+		/* set NaN as result */
+		result.bin = FLOAT64_NAN;
+		return result;
+	}
+	
+	if (is_float64_infinity(a)) {
+		if (is_float64_zero(b)) {
+			/* FIXME: zero * infinity */
+			result.bin = FLOAT64_NAN;
+			return result;
+		}
+		result.parts.fraction = a.parts.fraction;
+		result.parts.exp = a.parts.exp;
+		return result;
+	}
+	
+	if (is_float64_infinity(b)) {
+		if (is_float64_zero(a)) {
+			/* FIXME: zero * infinity */
+			result.bin = FLOAT64_NAN;
+			return result;
+		}
+		result.parts.fraction = b.parts.fraction;
+		result.parts.exp = b.parts.exp;
+		return result;
+	}
+	
+	/* exp is signed so we can easy detect underflow */
+	exp = a.parts.exp + b.parts.exp - FLOAT64_BIAS;
+	
+	frac1 = a.parts.fraction;
+	
+	if (a.parts.exp > 0) {
+		frac1 |= FLOAT64_HIDDEN_BIT_MASK;
+	} else {
+		++exp;
+	}
+	
+	frac2 = b.parts.fraction;
+	
+	if (b.parts.exp > 0) {
+		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
+	} else {
+		++exp;
+	}
+	
+	frac1 <<= (64 - FLOAT64_FRACTION_SIZE - 1);
+	frac2 <<= (64 - FLOAT64_FRACTION_SIZE - 2);
+	
+	mul64(frac1, frac2, &frac1, &frac2);
+	
+	frac1 |= (frac2 != 0);
+	if (frac1 & (0x1ll << 62)) {
+		frac1 <<= 1;
+		exp--;
+	}
+	
+	result = finish_float64(exp, frac1, result.parts.sign);
+	return result;
+}
+
+/** Multiply two quadruple-precision floats.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of multiplication.
+ *
+ */
+float128 mul_float128(float128 a, float128 b)
+{
+	float128 result;
+	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
+	int32_t exp;
+	
+	result.parts.sign = a.parts.sign ^ b.parts.sign;
+	
+	if (is_float128_nan(a) || is_float128_nan(b)) {
+		/* TODO: fix SigNaNs */
+		if (is_float128_signan(a)) {
+			result.parts.frac_hi = a.parts.frac_hi;
+			result.parts.frac_lo = a.parts.frac_lo;
+			result.parts.exp = a.parts.exp;
+			return result;
+		}
+		if (is_float128_signan(b)) { /* TODO: fix SigNaN */
+			result.parts.frac_hi = b.parts.frac_hi;
+			result.parts.frac_lo = b.parts.frac_lo;
+			result.parts.exp = b.parts.exp;
+			return result;
+		}
+		/* set NaN as result */
+		result.bin.hi = FLOAT128_NAN_HI;
+		result.bin.lo = FLOAT128_NAN_LO;
+		return result;
+	}
+	
+	if (is_float128_infinity(a)) {
+		if (is_float128_zero(b)) {
+			/* FIXME: zero * infinity */
+			result.bin.hi = FLOAT128_NAN_HI;
+			result.bin.lo = FLOAT128_NAN_LO;
+			return result;
+		}
+		result.parts.frac_hi = a.parts.frac_hi;
+		result.parts.frac_lo = a.parts.frac_lo;
+		result.parts.exp = a.parts.exp;
+		return result;
+	}
+	
+	if (is_float128_infinity(b)) {
+		if (is_float128_zero(a)) {
+			/* FIXME: zero * infinity */
+			result.bin.hi = FLOAT128_NAN_HI;
+			result.bin.lo = FLOAT128_NAN_LO;
+			return result;
+		}
+		result.parts.frac_hi = b.parts.frac_hi;
+		result.parts.frac_lo = b.parts.frac_lo;
+		result.parts.exp = b.parts.exp;
+		return result;
+	}
+	
+	/* exp is signed so we can easy detect underflow */
+	exp = a.parts.exp + b.parts.exp - FLOAT128_BIAS - 1;
+	
+	frac1_hi = a.parts.frac_hi;
+	frac1_lo = a.parts.frac_lo;
+	
+	if (a.parts.exp > 0) {
+		or128(frac1_hi, frac1_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &frac1_hi, &frac1_lo);
+	} else {
+		++exp;
+	}
+	
+	frac2_hi = b.parts.frac_hi;
+	frac2_lo = b.parts.frac_lo;
+	
+	if (b.parts.exp > 0) {
+		or128(frac2_hi, frac2_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &frac2_hi, &frac2_lo);
+	} else {
+		++exp;
+	}
+	
+	lshift128(frac2_hi, frac2_lo,
+	    128 - FLOAT128_FRACTION_SIZE, &frac2_hi, &frac2_lo);
+	
+	tmp_hi = frac1_hi;
+	tmp_lo = frac1_lo;
+	mul128(frac1_hi, frac1_lo, frac2_hi, frac2_lo,
+	    &frac1_hi, &frac1_lo, &frac2_hi, &frac2_lo);
+	add128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo);
+	frac2_hi |= (frac2_lo != 0x0ll);
+	
+	if ((FLOAT128_HIDDEN_BIT_MASK_HI << 1) <= frac1_hi) {
+		frac2_hi >>= 1;
+		if (frac1_lo & 0x1ll) {
+			frac2_hi |= (0x1ull < 64);
+		}
+		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
+		++exp;
+	}
+	
+	result = finish_float128(exp, frac1_hi, frac1_lo, result.parts.sign, frac2_hi);
+	return result;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/mul.h
===================================================================
--- uspace/lib/softfloat/mul.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/mul.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,47 @@
+/*
+ * 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 Multiplication functions.
+ */
+
+#ifndef __MUL_H__
+#define __MUL_H__
+
+extern float32 mul_float32(float32, float32);
+extern float64 mul_float64(float64, float64);
+extern float96 mul_float96(float96, float96);
+extern float128 mul_float128(float128, float128);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/other.c
===================================================================
--- uspace/lib/softfloat/other.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/other.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * 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 Other functions (power, complex).
+ */
+
+
+/** @}
+ */
Index: uspace/lib/softfloat/other.h
===================================================================
--- uspace/lib/softfloat/other.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/other.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2005 Josef Cejka
+ * 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 Other functions (power, complex).
+ */
+
+#ifndef __OTHER_H__
+#define __OTHER_H__
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/softfloat/sftypes.h
===================================================================
--- uspace/lib/softfloat/sftypes.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/sftypes.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,608 @@
+/*
+ * 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 __SFTYPES_H__
+#define __SFTYPES_H__
+
+#include <byteorder.h>
+#include <stdint.h>
+
+/*
+ * For recognizing NaNs or infinity use specialized comparison
+ * functions, comparing with these constants is not sufficient.
+ */
+
+#define FLOAT32_NAN     UINT32_C(0x7FC00001)
+#define FLOAT32_SIGNAN  UINT32_C(0x7F800001)
+#define FLOAT32_INF     UINT32_C(0x7F800000)
+
+#define FLOAT64_NAN     UINT64_C(0x7FF8000000000001)
+#define FLOAT64_SIGNAN  UINT64_C(0x7FF0000000000001)
+#define FLOAT64_INF     UINT64_C(0x7FF0000000000000)
+
+#define FLOAT96_NAN_HI     UINT64_C(0x7FFF80000000)
+#define FLOAT96_NAN_LO     UINT32_C(0x00010000)
+#define FLOAT96_SIGNAN_HI  UINT64_C(0x7FFF00000000)
+#define FLOAT96_SIGNAN_LO  UINT32_C(0x00010000)
+
+#define FLOAT128_NAN_HI     UINT64_C(0x7FFF800000000000)
+#define FLOAT128_NAN_LO     UINT64_C(0x0000000000000001)
+#define FLOAT128_SIGNAN_HI  UINT64_C(0x7FFF000000000000)
+#define FLOAT128_SIGNAN_LO  UINT64_C(0x0000000000000001)
+#define FLOAT128_INF_HI     UINT64_C(0x7FFF000000000000)
+#define FLOAT128_INF_LO     UINT64_C(0x0000000000000000)
+
+#define FLOAT32_FRACTION_SIZE   23
+#define FLOAT64_FRACTION_SIZE   52
+#define FLOAT96_FRACTION_SIZE   64
+#define FLOAT128_FRACTION_SIZE  112
+#define FLOAT128_FRAC_HI_SIZE   48
+#define FLOAT128_FRAC_LO_SIZE   64
+
+#define FLOAT32_HIDDEN_BIT_MASK      UINT32_C(0x800000)
+#define FLOAT64_HIDDEN_BIT_MASK      UINT64_C(0x10000000000000)
+#define FLOAT128_HIDDEN_BIT_MASK_HI  UINT64_C(0x1000000000000)
+#define FLOAT128_HIDDEN_BIT_MASK_LO  UINT64_C(0x0000000000000000)
+
+#define FLOAT32_MAX_EXPONENT   0xFF
+#define FLOAT64_MAX_EXPONENT   0x7FF
+#define FLOAT96_MAX_EXPONENT   0x7FFF
+#define FLOAT128_MAX_EXPONENT  0x7FFF
+
+#define FLOAT32_BIAS   0x7F
+#define FLOAT64_BIAS   0x3FF
+#define FLOAT96_BIAS   0x3FFF
+#define FLOAT128_BIAS  0x3FFF
+
+#if defined(__BE__)
+
+typedef union {
+	uint32_t bin;
+	
+	struct {
+		uint32_t sign : 1;
+		uint32_t exp : 8;
+		uint32_t fraction : 23;
+	} parts __attribute__((packed));
+} float32;
+
+typedef union {
+	uint64_t bin;
+	
+	struct {
+		uint64_t sign : 1;
+		uint64_t exp : 11;
+		uint64_t fraction : 52;
+	} parts __attribute__((packed));
+} float64;
+
+typedef union {
+	struct {
+		uint64_t hi;
+		uint32_t lo;
+	} bin __attribute__((packed));
+	
+	struct {
+		uint64_t padding : 16;
+		uint64_t sign : 1;
+		uint64_t exp : 15;
+		uint64_t fraction : 64;
+	} parts __attribute__((packed));
+} float96;
+
+typedef union {
+	struct {
+		uint64_t hi;
+		uint64_t lo;
+	} bin __attribute__((packed));
+	
+	struct {
+		uint64_t sign : 1;
+		uint64_t exp : 15;
+		uint64_t frac_hi : 48;
+		uint64_t frac_lo : 64;
+	} parts __attribute__((packed));
+} float128;
+
+#elif defined(__LE__)
+
+typedef union {
+	uint32_t bin;
+	
+	struct {
+		uint32_t fraction : 23;
+		uint32_t exp : 8;
+		uint32_t sign : 1;
+	} parts __attribute__((packed));
+} float32;
+
+typedef union {
+	uint64_t bin;
+	
+	struct {
+		uint64_t fraction : 52;
+		uint64_t exp : 11;
+		uint64_t sign : 1;
+	} parts __attribute__((packed));
+} float64;
+
+typedef union {
+	struct {
+		uint32_t lo;
+		uint64_t hi;
+	} bin __attribute__((packed));
+	
+	struct {
+		uint64_t fraction : 64;
+		uint64_t exp : 15;
+		uint64_t sign : 1;
+		uint64_t padding : 16;
+	} parts __attribute__((packed));
+} float96;
+
+typedef union {
+	struct {
+		uint64_t lo;
+		uint64_t hi;
+	} bin __attribute__((packed));
+	
+	struct {
+		uint64_t frac_lo : 64;
+		uint64_t frac_hi : 48;
+		uint64_t exp : 15;
+		uint64_t sign : 1;
+	} parts __attribute__((packed));
+} float128;
+
+#else
+	#error Unknown endianess
+#endif
+
+typedef union {
+	float val;
+	
+#if defined(FLOAT_SIZE_32)
+	float32 data;
+#elif defined(FLOAT_SIZE_64)
+	float64 data;
+#elif defined(FLOAT_SIZE_96)
+	float96 data;
+#elif defined(FLOAT_SIZE_128)
+	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;
+
+
+#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: uspace/lib/softfloat/softfloat.c
===================================================================
--- uspace/lib/softfloat/softfloat.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/softfloat.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,1353 @@
+/*
+ * 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"
+#include "other.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);
+}
+
+double __aeabi_i2d(int i)
+{
+	return __floatsidf(i);
+}
+
+double __aeabi_ui2d(unsigned int i)
+{
+	return __floatunsidf(i);
+}
+
+int __aeabi_f2iz(float a)
+{
+	return __fixsfsi(a);
+}
+
+int __aeabi_d2iz(double a)
+{
+	return __fixdfsi(a);
+}
+
+unsigned int __aeabi_d2uiz(double a)
+{
+	return __fixunsdfsi(a);
+}
+
+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_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: uspace/lib/softfloat/softfloat.h
===================================================================
--- uspace/lib/softfloat/softfloat.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/softfloat.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,234 @@
+/*
+ * 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 double __aeabi_i2d(int);
+extern double __aeabi_ui2d(unsigned int);
+extern unsigned int __aeabi_d2uiz(double);
+
+extern int __aeabi_f2iz(float);
+extern int __aeabi_d2iz(double);
+
+extern int __aeabi_dcmpge(double, double);
+extern int __aeabi_dcmpgt(double, double);
+extern int __aeabi_dcmplt(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 fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/sub.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,441 @@
+/*
+ * 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 Substraction functions.
+ */
+
+#include "sftypes.h"
+#include "sub.h"
+#include "comparison.h"
+#include "common.h"
+
+/** Subtract two single-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of substraction.
+ *
+ */
+float32 sub_float32(float32 a, float32 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2, frac1, frac2;
+	float32 result;
+	
+	result.bin = 0;
+	
+	expdiff = a.parts.exp - b.parts.exp;
+	if ((expdiff < 0 ) || ((expdiff == 0) &&
+	    (a.parts.fraction < b.parts.fraction))) {
+		if (is_float32_nan(b)) {
+			if (is_float32_signan(b)) {
+				// TODO: fix SigNaN
+			}
+			
+			return b;
+		}
+		
+		if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
+			/* num -(+-inf) = -+inf */
+			b.parts.sign = !b.parts.sign;
+			return b;
+		}
+		
+		result.parts.sign = !a.parts.sign;
+		
+		frac1 = b.parts.fraction;
+		exp1 = b.parts.exp;
+		frac2 = a.parts.fraction;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if (is_float32_nan(a)) {
+			if ((is_float32_signan(a)) || (is_float32_signan(b))) {
+				// TODO: fix SigNaN
+			}
+			
+			return a;
+		}
+		
+		if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
+			if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
+				/* inf - inf => nan */
+				// TODO: fix exception
+				result.bin = FLOAT32_NAN;
+				return result;
+			}
+			
+			return a;
+		}
+		
+		result.parts.sign = a.parts.sign;
+		
+		frac1 = a.parts.fraction;
+		exp1 = a.parts.exp;
+		frac2 = b.parts.fraction;
+		exp2 = b.parts.exp;
+	}
+	
+	if (exp1 == 0) {
+		/* both are denormalized */
+		result.parts.fraction = frac1 - frac2;
+		if (result.parts.fraction > frac1) {
+			// TODO: underflow exception
+			return result;
+		}
+		
+		result.parts.exp = 0;
+		return result;
+	}
+	
+	/* add hidden bit */
+	frac1 |= FLOAT32_HIDDEN_BIT_MASK;
+	
+	if (exp2 == 0) {
+		/* denormalized */
+		--expdiff;
+	} else {
+		/* normalized */
+		frac2 |= FLOAT32_HIDDEN_BIT_MASK;
+	}
+	
+	/* create some space for rounding */
+	frac1 <<= 6;
+	frac2 <<= 6;
+	
+	if (expdiff > FLOAT32_FRACTION_SIZE + 1)
+		goto done;
+	
+	frac1 = frac1 - (frac2 >> expdiff);
+	
+done:
+	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
+	while ((exp1 > 0) && (!(frac1 & (FLOAT32_HIDDEN_BIT_MASK << 6 )))) {
+		--exp1;
+		frac1 <<= 1;
+		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
+	}
+	
+	/* rounding - if first bit after fraction is set then round up */
+	frac1 += 0x20;
+	
+	if (frac1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	/* Clear hidden bit and shift */
+	result.parts.fraction = ((frac1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
+	result.parts.exp = exp1;
+	
+	return result;
+}
+
+/** Subtract two double-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of substraction.
+ *
+ */
+float64 sub_float64(float64 a, float64 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2;
+	uint64_t frac1, frac2;
+	float64 result;
+	
+	result.bin = 0;
+	
+	expdiff = a.parts.exp - b.parts.exp;
+	if ((expdiff < 0 ) ||
+	    ((expdiff == 0) && (a.parts.fraction < b.parts.fraction))) {
+		if (is_float64_nan(b)) {
+			if (is_float64_signan(b)) {
+				// TODO: fix SigNaN
+			}
+			
+			return b;
+		}
+		
+		if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
+			/* num -(+-inf) = -+inf */
+			b.parts.sign = !b.parts.sign;
+			return b;
+		}
+		
+		result.parts.sign = !a.parts.sign;
+		
+		frac1 = b.parts.fraction;
+		exp1 = b.parts.exp;
+		frac2 = a.parts.fraction;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if (is_float64_nan(a)) {
+			if (is_float64_signan(a) || is_float64_signan(b)) {
+				// TODO: fix SigNaN
+			}
+			
+			return a;
+		}
+		
+		if (a.parts.exp == FLOAT64_MAX_EXPONENT) {
+			if (b.parts.exp == FLOAT64_MAX_EXPONENT) {
+				/* inf - inf => nan */
+				// TODO: fix exception
+				result.bin = FLOAT64_NAN;
+				return result;
+			}
+			
+			return a;
+		}
+		
+		result.parts.sign = a.parts.sign;
+		
+		frac1 = a.parts.fraction;
+		exp1 = a.parts.exp;
+		frac2 = b.parts.fraction;
+		exp2 = b.parts.exp;
+	}
+	
+	if (exp1 == 0) {
+		/* both are denormalized */
+		result.parts.fraction = frac1 - frac2;
+		if (result.parts.fraction > frac1) {
+			// TODO: underflow exception
+			return result;
+		}
+		
+		result.parts.exp = 0;
+		return result;
+	}
+	
+	/* add hidden bit */
+	frac1 |= FLOAT64_HIDDEN_BIT_MASK;
+	
+	if (exp2 == 0) {
+		/* denormalized */
+		--expdiff;
+	} else {
+		/* normalized */
+		frac2 |= FLOAT64_HIDDEN_BIT_MASK;
+	}
+	
+	/* create some space for rounding */
+	frac1 <<= 6;
+	frac2 <<= 6;
+	
+	if (expdiff > FLOAT64_FRACTION_SIZE + 1)
+		goto done;
+	
+	frac1 = frac1 - (frac2 >> expdiff);
+	
+done:
+	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
+	while ((exp1 > 0) && (!(frac1 & (FLOAT64_HIDDEN_BIT_MASK << 6 )))) {
+		--exp1;
+		frac1 <<= 1;
+		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
+	}
+	
+	/* rounding - if first bit after fraction is set then round up */
+	frac1 += 0x20;
+	
+	if (frac1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
+		++exp1;
+		frac1 >>= 1;
+	}
+	
+	/* Clear hidden bit and shift */
+	result.parts.fraction = ((frac1 >> 6) & (~FLOAT64_HIDDEN_BIT_MASK));
+	result.parts.exp = exp1;
+	
+	return result;
+}
+
+/** Subtract two quadruple-precision floats with the same sign.
+ *
+ * @param a First input operand.
+ * @param b Second input operand.
+ *
+ * @return Result of substraction.
+ *
+ */
+float128 sub_float128(float128 a, float128 b)
+{
+	int expdiff;
+	uint32_t exp1, exp2;
+	uint64_t frac1_hi, frac1_lo, frac2_hi, frac2_lo, tmp_hi, tmp_lo;
+	float128 result;
+	
+	result.bin.hi = 0;
+	result.bin.lo = 0;
+	
+	expdiff = a.parts.exp - b.parts.exp;
+	if ((expdiff < 0 ) || ((expdiff == 0) &&
+	    lt128(a.parts.frac_hi, a.parts.frac_lo, b.parts.frac_hi, b.parts.frac_lo))) {
+		if (is_float128_nan(b)) {
+			if (is_float128_signan(b)) {
+				// TODO: fix SigNaN
+			}
+			
+			return b;
+		}
+		
+		if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
+			/* num -(+-inf) = -+inf */
+			b.parts.sign = !b.parts.sign;
+			return b;
+		}
+		
+		result.parts.sign = !a.parts.sign;
+		
+		frac1_hi = b.parts.frac_hi;
+		frac1_lo = b.parts.frac_lo;
+		exp1 = b.parts.exp;
+		frac2_hi = a.parts.frac_hi;
+		frac2_lo = a.parts.frac_lo;
+		exp2 = a.parts.exp;
+		expdiff *= -1;
+	} else {
+		if (is_float128_nan(a)) {
+			if (is_float128_signan(a) || is_float128_signan(b)) {
+				// TODO: fix SigNaN
+			}
+			
+			return a;
+		}
+		
+		if (a.parts.exp == FLOAT128_MAX_EXPONENT) {
+			if (b.parts.exp == FLOAT128_MAX_EXPONENT) {
+				/* inf - inf => nan */
+				// TODO: fix exception
+				result.bin.hi = FLOAT128_NAN_HI;
+				result.bin.lo = FLOAT128_NAN_LO;
+				return result;
+			}
+			return a;
+		}
+		
+		result.parts.sign = a.parts.sign;
+		
+		frac1_hi = a.parts.frac_hi;
+		frac1_lo = a.parts.frac_lo;
+		exp1 = a.parts.exp;
+		frac2_hi = b.parts.frac_hi;
+		frac2_lo = b.parts.frac_lo;
+		exp2 = b.parts.exp;
+	}
+	
+	if (exp1 == 0) {
+		/* both are denormalized */
+		sub128(frac1_hi, frac1_lo, frac2_hi, frac2_lo, &tmp_hi, &tmp_lo);
+		result.parts.frac_hi = tmp_hi;
+		result.parts.frac_lo = tmp_lo;
+		if (lt128(frac1_hi, frac1_lo, result.parts.frac_hi, result.parts.frac_lo)) {
+			// TODO: underflow exception
+			return result;
+		}
+		
+		result.parts.exp = 0;
+		return result;
+	}
+	
+	/* add hidden bit */
+	or128(frac1_hi, frac1_lo,
+	    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &frac1_hi, &frac1_lo);
+	
+	if (exp2 == 0) {
+		/* denormalized */
+		--expdiff;
+	} else {
+		/* normalized */
+		or128(frac2_hi, frac2_lo,
+		    FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+		    &frac2_hi, &frac2_lo);
+	}
+	
+	/* create some space for rounding */
+	lshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
+	lshift128(frac2_hi, frac2_lo, 6, &frac2_hi, &frac2_lo);
+	
+	if (expdiff > FLOAT128_FRACTION_SIZE + 1)
+		goto done;
+	
+	rshift128(frac2_hi, frac2_lo, expdiff, &tmp_hi, &tmp_lo);
+	sub128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &frac1_hi, &frac1_lo);
+	
+done:
+	/* TODO: find first nonzero digit and shift result and detect possibly underflow */
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6,
+	    &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	while ((exp1 > 0) && (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo))) {
+		--exp1;
+		lshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
+		/* TODO: fix underflow - frac1 == 0 does not necessary means underflow... */
+		
+		lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 6,
+		    &tmp_hi, &tmp_lo);
+		and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	}
+	
+	/* rounding - if first bit after fraction is set then round up */
+	add128(frac1_hi, frac1_lo, 0x0ll, 0x20ll, &frac1_hi, &frac1_lo);
+	
+	lshift128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO, 7,
+	   &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	if (lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
+		++exp1;
+		rshift128(frac1_hi, frac1_lo, 1, &frac1_hi, &frac1_lo);
+	}
+	
+	/* Clear hidden bit and shift */
+	rshift128(frac1_hi, frac1_lo, 6, &frac1_hi, &frac1_lo);
+	not128(FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
+	    &tmp_hi, &tmp_lo);
+	and128(frac1_hi, frac1_lo, tmp_hi, tmp_lo, &tmp_hi, &tmp_lo);
+	result.parts.frac_hi = tmp_hi;
+	result.parts.frac_lo = tmp_lo;
+	
+	result.parts.exp = exp1;
+	
+	return result;
+}
+
+/** @}
+ */
Index: uspace/lib/softfloat/sub.h
===================================================================
--- uspace/lib/softfloat/sub.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/lib/softfloat/sub.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,47 @@
+/*
+ * 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 Substraction functions.
+ */
+
+#ifndef __SUB_H__
+#define __SUB_H__
+
+extern float32 sub_float32(float32, float32);
+extern float64 sub_float64(float64, float64);
+extern float96 sub_float96(float96, float96);
+extern float128 sub_float128(float128, float128);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/usb/include/usb/debug.h
===================================================================
--- uspace/lib/usb/include/usb/debug.h	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/usb/include/usb/debug.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -38,4 +38,5 @@
 #include <inttypes.h>
 #include <usb/usb.h>
+#include <io/log.h>
 #include <assert.h>
 
@@ -43,52 +44,13 @@
     const uint8_t *, size_t);
 
-/** Logging level. */
-typedef enum {
-	/** Fatal, unrecoverable, error.
-	 * Such error prevents the driver from working at all.
-	 */
-	USB_LOG_LEVEL_FATAL,
+#define USB_LOG_LEVEL_FATAL LVL_FATAL
+#define USB_LOG_LEVEL_ERROR LVL_ERROR
+#define USB_LOG_LEVEL_WARNING LVL_WARN
+#define USB_LOG_LEVEL_INFO LVL_NOTE
+#define USB_LOG_LEVEL_DEBUG LVL_DEBUG
+#define USB_LOG_LEVEL_DEBUG2 LVL_DEBUG2
 
-	/** Serious but recoverable error
-	 * Shall be used for errors fatal for single device but not for
-	 * driver itself.
-	 */
-	USB_LOG_LEVEL_ERROR,
-
-	/** Warning.
-	 * Problems from which the driver is able to recover gracefully.
-	 */
-	USB_LOG_LEVEL_WARNING,
-
-	/** Information message.
-	 * This should be the last level that is printed by default to
-	 * the screen.
-	 * Typical usage is to inform that new device was found and what
-	 * are its capabilities.
-	 * Do not use for repetitive actions (such as device polling).
-	 */
-	USB_LOG_LEVEL_INFO,
-
-	/** Debugging message. */
-	USB_LOG_LEVEL_DEBUG,
-
-	/** More detailed debugging message. */
-	USB_LOG_LEVEL_DEBUG2,
-
-	/** Terminating constant for logging levels. */
-	USB_LOG_LEVEL_MAX
-} usb_log_level_t;
-
-/** Default log level. */
-#ifdef CONFIG_USB_VERBOSE
-	#define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_DEBUG
-#else
-	#define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_INFO
-#endif
-
-void usb_log_enable(usb_log_level_t, const char *);
-
-void usb_log_printf(usb_log_level_t, const char *, ...)
-	PRINTF_ATTRIBUTE(2, 3);
+#define usb_log_printf(level, format, ...) \
+	log_msg(LOG_DEFAULT, level, format, ##__VA_ARGS__)
 
 /** Log fatal error. */
Index: uspace/lib/usb/src/debug.c
===================================================================
--- uspace/lib/usb/src/debug.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/lib/usb/src/debug.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -40,115 +40,4 @@
 #include <ddf/log.h>
 #include <usb/debug.h>
-
-/** Level of logging messages. */
-static usb_log_level_t log_level = USB_LOG_LEVEL_WARNING;
-
-/** Prefix for logging messages. */
-static const char *log_prefix = "usb";
-
-/** Serialization mutex for logging functions. */
-static FIBRIL_MUTEX_INITIALIZE(log_serializer);
-
-/** File where to store the log. */
-static FILE *log_stream = NULL;
-
-
-/** Enable logging.
- *
- * @param level Maximal enabled level (including this one).
- * @param message_prefix Prefix for each printed message.
- */
-void usb_log_enable(usb_log_level_t level, const char *message_prefix)
-{
-	log_prefix = message_prefix;
-	log_level = level;
-	if (log_stream == NULL) {
-		char *fname;
-		int rc = asprintf(&fname, "/log/%s", message_prefix);
-		if (rc > 0) {
-			log_stream = fopen(fname, "w");
-			if (log_stream != NULL)
-				setvbuf(log_stream, NULL, _IOFBF, BUFSIZ);
-			
-			free(fname);
-		}
-	}
-}
-
-/** Get log level name prefix.
- *
- * @param level Log level.
- * @return String prefix for the message.
- */
-static const char *log_level_name(usb_log_level_t level)
-{
-	switch (level) {
-		case USB_LOG_LEVEL_FATAL:
-			return " FATAL";
-		case USB_LOG_LEVEL_ERROR:
-			return " ERROR";
-		case USB_LOG_LEVEL_WARNING:
-			return " WARN";
-		case USB_LOG_LEVEL_INFO:
-			return " info";
-		default:
-			return "";
-	}
-}
-
-/** Print logging message.
- *
- * @param level Verbosity level of the message.
- * @param format Formatting directive.
- */
-void usb_log_printf(usb_log_level_t level, const char *format, ...)
-{
-	FILE *screen_stream = NULL;
-	switch (level) {
-		case USB_LOG_LEVEL_FATAL:
-		case USB_LOG_LEVEL_ERROR:
-			screen_stream = stderr;
-			break;
-		default:
-			screen_stream = stdout;
-			break;
-	}
-	assert(screen_stream != NULL);
-
-	va_list args;
-
-	/*
-	 * Serialize access to log files.
-	 * Print to screen only messages with higher level than the one
-	 * specified during logging initialization.
-	 * Print also to file, to it print one more (lower) level as well.
-	 */
-	fibril_mutex_lock(&log_serializer);
-
-	const char *level_name = log_level_name(level);
-
-	if ((log_stream != NULL) && (level <= log_level + 1)) {
-		va_start(args, format);
-
-		fprintf(log_stream, "[%s]%s: ", log_prefix, level_name);
-		vfprintf(log_stream, format, args);
-		fflush(log_stream);
-
-		va_end(args);
-	}
-
-	if (level <= log_level) {
-		va_start(args, format);
-
-		fprintf(screen_stream, "[%s]%s: ", log_prefix, level_name);
-		vfprintf(screen_stream, format, args);
-		fflush(screen_stream);
-
-		va_end(args);
-	}
-
-	fibril_mutex_unlock(&log_serializer);
-}
-
 
 #define REMAINDER_STR_FMT " (%zu)..."
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/devman/devman.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -151,5 +151,5 @@
 	fibril_mutex_unlock(&drivers_list->drivers_mutex);
 
-	log_msg(LVL_NOTE, "Driver `%s' was added to the list of available "
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Driver `%s' was added to the list of available "
 	    "drivers.", drv->name);
 }
@@ -242,5 +242,5 @@
 bool read_match_ids(const char *conf_path, match_id_list_t *ids)
 {
-	log_msg(LVL_DEBUG, "read_match_ids(conf_path=\"%s\")", conf_path);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "read_match_ids(conf_path=\"%s\")", conf_path);
 	
 	bool suc = false;
@@ -252,5 +252,5 @@
 	fd = open(conf_path, O_RDONLY);
 	if (fd < 0) {
-		log_msg(LVL_ERROR, "Unable to open `%s' for reading: %s.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to open `%s' for reading: %s.",
 		    conf_path, str_error(fd));
 		goto cleanup;
@@ -261,5 +261,5 @@
 	lseek(fd, 0, SEEK_SET);
 	if (len == 0) {
-		log_msg(LVL_ERROR, "Configuration file '%s' is empty.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Configuration file '%s' is empty.",
 		    conf_path);
 		goto cleanup;
@@ -268,5 +268,5 @@
 	buf = malloc(len + 1);
 	if (buf == NULL) {
-		log_msg(LVL_ERROR, "Memory allocation failed when parsing file "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failed when parsing file "
 		    "'%s'.", conf_path);
 		goto cleanup;
@@ -275,5 +275,5 @@
 	ssize_t read_bytes = read_all(fd, buf, len);
 	if (read_bytes <= 0) {
-		log_msg(LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path,
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to read file '%s' (%zd).", conf_path,
 		    read_bytes);
 		goto cleanup;
@@ -314,5 +314,5 @@
 bool get_driver_info(const char *base_path, const char *name, driver_t *drv)
 {
-	log_msg(LVL_DEBUG, "get_driver_info(base_path=\"%s\", name=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "get_driver_info(base_path=\"%s\", name=\"%s\")",
 	    base_path, name);
 	
@@ -346,5 +346,5 @@
 	struct stat s;
 	if (stat(drv->binary_path, &s) == ENOENT) { /* FIXME!! */
-		log_msg(LVL_ERROR, "Driver not found at path `%s'.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Driver not found at path `%s'.",
 		    drv->binary_path);
 		goto cleanup;
@@ -374,5 +374,5 @@
 int lookup_available_drivers(driver_list_t *drivers_list, const char *dir_path)
 {
-	log_msg(LVL_DEBUG, "lookup_available_drivers(dir=\"%s\")", dir_path);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "lookup_available_drivers(dir=\"%s\")", dir_path);
 	
 	int drv_cnt = 0;
@@ -408,5 +408,5 @@
 	dev_node_t *dev;
 	
-	log_msg(LVL_DEBUG, "create_root_nodes()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "create_root_nodes()");
 	
 	fibril_rwlock_write_lock(&tree->rwlock);
@@ -495,5 +495,5 @@
 void attach_driver(dev_tree_t *tree, dev_node_t *dev, driver_t *drv)
 {
-	log_msg(LVL_DEBUG, "attach_driver(dev=\"%s\",drv=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "attach_driver(dev=\"%s\",drv=\"%s\")",
 	    dev->pfun->pathname, drv->name);
 	
@@ -520,5 +520,5 @@
 	assert(drv != NULL);
 	
-	log_msg(LVL_DEBUG, "detach_driver(dev=\"%s\",drv=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "detach_driver(dev=\"%s\",drv=\"%s\")",
 	    dev->pfun->pathname, drv->name);
 	
@@ -545,9 +545,9 @@
 	assert(fibril_mutex_is_locked(&drv->driver_mutex));
 	
-	log_msg(LVL_DEBUG, "start_driver(drv=\"%s\")", drv->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "start_driver(drv=\"%s\")", drv->name);
 	
 	rc = task_spawnl(NULL, drv->binary_path, drv->binary_path, NULL);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Spawning driver `%s' (%s) failed: %s.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Spawning driver `%s' (%s) failed: %s.",
 		    drv->name, drv->binary_path, str_error(rc));
 		return false;
@@ -594,5 +594,5 @@
 	link_t *link;
 
-	log_msg(LVL_DEBUG, "pass_devices_to_driver(driver=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pass_devices_to_driver(driver=\"%s\")",
 	    driver->name);
 
@@ -614,5 +614,5 @@
 		}
 
-		log_msg(LVL_DEBUG, "pass_devices_to_driver: dev->refcnt=%d\n",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "pass_devices_to_driver: dev->refcnt=%d\n",
 		    (int)atomic_get(&dev->refcnt));
 		dev_add_ref(dev);
@@ -650,5 +650,5 @@
 	 * immediately and possibly started here as well.
 	 */
-	log_msg(LVL_DEBUG, "Driver `%s' enters running state.", driver->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Driver `%s' enters running state.", driver->name);
 	driver->state = DRIVER_RUNNING;
 
@@ -667,5 +667,5 @@
 void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
 {
-	log_msg(LVL_DEBUG, "initialize_running_driver(driver=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "initialize_running_driver(driver=\"%s\")",
 	    driver->name);
 	
@@ -761,5 +761,5 @@
 	 * access any structures that would affect driver_t.
 	 */
-	log_msg(LVL_DEBUG, "add_device(drv=\"%s\", dev=\"%s\")",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "add_device(drv=\"%s\", dev=\"%s\")",
 	    drv->name, dev->pfun->name);
 	
@@ -827,5 +827,5 @@
 	driver_t *drv = find_best_match_driver(drivers_list, dev);
 	if (drv == NULL) {
-		log_msg(LVL_ERROR, "No driver found for device `%s'.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "No driver found for device `%s'.",
 		    dev->pfun->pathname);
 		return false;
@@ -867,5 +867,5 @@
 	assert(dev != NULL);
 	
-	log_msg(LVL_DEBUG, "driver_dev_remove(%p)", dev);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_remove(%p)", dev);
 	
 	fibril_rwlock_read_lock(&tree->rwlock);
@@ -890,5 +890,5 @@
 	assert(dev != NULL);
 	
-	log_msg(LVL_DEBUG, "driver_dev_gone(%p)", dev);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_dev_gone(%p)", dev);
 	
 	fibril_rwlock_read_lock(&tree->rwlock);
@@ -911,5 +911,5 @@
 	devman_handle_t handle;
 	
-	log_msg(LVL_DEBUG, "driver_fun_online(%p)", fun);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_fun_online(%p)", fun);
 
 	fibril_rwlock_read_lock(&tree->rwlock);
@@ -939,5 +939,5 @@
 	devman_handle_t handle;
 	
-	log_msg(LVL_DEBUG, "driver_fun_offline(%p)", fun);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "driver_fun_offline(%p)", fun);
 
 	fibril_rwlock_read_lock(&tree->rwlock);
@@ -970,5 +970,5 @@
 bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list)
 {
-	log_msg(LVL_DEBUG, "init_device_tree()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "init_device_tree()");
 	
 	tree->current_handle = 0;
@@ -1261,5 +1261,5 @@
 	fun->pathname = (char *) malloc(pathsize);
 	if (fun->pathname == NULL) {
-		log_msg(LVL_ERROR, "Failed to allocate device path.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate device path.");
 		return false;
 	}
@@ -1289,5 +1289,5 @@
 	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
 	
-	log_msg(LVL_DEBUG, "insert_dev_node(dev=%p, pfun=%p [\"%s\"])",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "insert_dev_node(dev=%p, pfun=%p [\"%s\"])",
 	    dev, pfun, pfun->pathname);
 
@@ -1313,5 +1313,5 @@
 	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
 	
-	log_msg(LVL_DEBUG, "remove_dev_node(dev=%p)", dev);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "remove_dev_node(dev=%p)", dev);
 	
 	/* Remove node from the handle-to-node map. */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/devman/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -73,5 +73,5 @@
 	char *drv_name = NULL;
 
-	log_msg(LVL_DEBUG, "devman_driver_register");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_driver_register");
 	
 	/* Get driver name. */
@@ -82,5 +82,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "The `%s' driver is trying to register.",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "The `%s' driver is trying to register.",
 	    drv_name);
 	
@@ -88,5 +88,5 @@
 	driver = find_driver(&drivers_list, drv_name);
 	if (driver == NULL) {
-		log_msg(LVL_ERROR, "No driver named `%s' was found.", drv_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "No driver named `%s' was found.", drv_name);
 		free(drv_name);
 		drv_name = NULL;
@@ -102,5 +102,5 @@
 	if (driver->sess) {
 		/* We already have a connection to the driver. */
-		log_msg(LVL_ERROR, "Driver '%s' already started.\n",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Driver '%s' already started.\n",
 		    driver->name);
 		fibril_mutex_unlock(&driver->driver_mutex);
@@ -112,5 +112,5 @@
 	case DRIVER_NOT_STARTED:
 		/* Somebody started the driver manually. */
-		log_msg(LVL_NOTE, "Driver '%s' started manually.\n",
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Driver '%s' started manually.\n",
 		    driver->name);
 		driver->state = DRIVER_STARTING;
@@ -125,5 +125,5 @@
 	
 	/* Create connection to the driver. */
-	log_msg(LVL_DEBUG, "Creating connection to the `%s' driver.",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Creating connection to the `%s' driver.",
 	    driver->name);
 	driver->sess = async_callback_receive(EXCHANGE_PARALLEL);
@@ -136,5 +136,5 @@
 	async_sess_args_set(driver->sess, DRIVER_DEVMAN, 0, 0);
 	
-	log_msg(LVL_NOTE,
+	log_msg(LOG_DEFAULT, LVL_NOTE,
 	    "The `%s' driver was successfully registered as running.",
 	    driver->name);
@@ -147,5 +147,5 @@
 	fid_t fid = fibril_create(init_running_drv, driver);
 	if (fid == 0) {
-		log_msg(LVL_ERROR, "Failed to create initialization fibril " \
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to create initialization fibril " \
 		    "for driver `%s'.", driver->name);
 		fibril_mutex_unlock(&driver->driver_mutex);
@@ -176,5 +176,5 @@
 	callid = async_get_call(&call);
 	if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) {
-		log_msg(LVL_ERROR, 
+		log_msg(LOG_DEFAULT, LVL_ERROR, 
 		    "Invalid protocol when trying to receive match id.");
 		async_answer_0(callid, EINVAL); 
@@ -184,5 +184,5 @@
 	
 	if (match_id == NULL) {
-		log_msg(LVL_ERROR, "Failed to allocate match id.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate match id.");
 		async_answer_0(callid, ENOMEM);
 		return ENOMEM;
@@ -198,5 +198,5 @@
 	if (rc != EOK) {
 		delete_match_id(match_id);
-		log_msg(LVL_ERROR, "Failed to receive match id string: %s.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to receive match id string: %s.",
 		    str_error(rc));
 		return rc;
@@ -205,5 +205,5 @@
 	list_append(&match_id->link, &match_ids->ids);
 	
-	log_msg(LVL_DEBUG, "Received match id `%s', score %d.",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Received match id `%s', score %d.",
 	    match_id->id, match_id->score);
 	return rc;
@@ -248,5 +248,5 @@
 	if (fun->state == FUN_ON_LINE) {
 		fibril_rwlock_write_unlock(&device_tree.rwlock);
-		log_msg(LVL_WARN, "Function %s is already on line.",
+		log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already on line.",
 		    fun->pathname);
 		return EOK;
@@ -264,5 +264,5 @@
 	}
 	
-	log_msg(LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_add_function(fun=\"%s\")", fun->pathname);
 	
 	if (fun->ftype == fun_inner) {
@@ -282,5 +282,5 @@
 		fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
 		if (assign_fibril == 0) {
-			log_msg(LVL_ERROR, "Failed to create fibril for "
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to create fibril for "
 			    "assigning driver.");
 			/* XXX Cleanup */
@@ -305,5 +305,5 @@
 	if (fun->state == FUN_OFF_LINE) {
 		fibril_rwlock_write_unlock(&device_tree.rwlock);
-		log_msg(LVL_WARN, "Function %s is already off line.",
+		log_msg(LOG_DEFAULT, LVL_WARN, "Function %s is already off line.",
 		    fun->pathname);
 		return EOK;
@@ -311,5 +311,5 @@
 	
 	if (fun->ftype == fun_inner) {
-		log_msg(LVL_DEBUG, "Offlining inner function %s.",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Offlining inner function %s.",
 		    fun->pathname);
 		
@@ -359,5 +359,5 @@
 		if (rc != EOK) {
 			fibril_rwlock_write_unlock(&device_tree.rwlock);
-			log_msg(LVL_ERROR, "Failed unregistering tree service.");
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unregistering tree service.");
 			return EIO;
 		}
@@ -391,5 +391,5 @@
 	if (ftype != fun_inner && ftype != fun_exposed) {
 		/* Unknown function type */
-		log_msg(LVL_ERROR, 
+		log_msg(LOG_DEFAULT, LVL_ERROR, 
 		    "Unknown function type %d provided by driver.",
 		    (int) ftype);
@@ -507,8 +507,8 @@
 	if (rc == EOK) {
 		loc_service_add_to_cat(fun->service_id, cat_id);
-		log_msg(LVL_NOTE, "Function `%s' added to category `%s'.",
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Function `%s' added to category `%s'.",
 		    fun->pathname, cat_name);
 	} else {
-		log_msg(LVL_ERROR, "Failed adding function `%s' to category "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding function `%s' to category "
 		    "`%s'.", fun->pathname, cat_name);
 	}
@@ -529,5 +529,5 @@
 	int rc;
 	
-	log_msg(LVL_DEBUG, "devman_drv_fun_online()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_drv_fun_online()");
 	
 	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
@@ -620,5 +620,5 @@
 	fibril_rwlock_write_lock(&tree->rwlock);
 	
-	log_msg(LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_remove_function(fun='%s')", fun->pathname);
 	
 	/* Check function state */
@@ -653,5 +653,5 @@
 			/* Verify that driver succeeded and removed all functions */
 			if (gone_rc != EOK || !list_empty(&dev->functions)) {
-				log_msg(LVL_ERROR, "Driver did not remove "
+				log_msg(LOG_DEFAULT, LVL_ERROR, "Driver did not remove "
 				    "functions for device that is gone. "
 				    "Device node is now defunct.");
@@ -692,5 +692,5 @@
 			rc = loc_service_unregister(fun->service_id);
 			if (rc != EOK) {
-				log_msg(LVL_ERROR, "Failed unregistering tree "
+				log_msg(LOG_DEFAULT, LVL_ERROR, "Failed unregistering tree "
 				    "service.");
 				fibril_rwlock_write_unlock(&tree->rwlock);
@@ -712,5 +712,5 @@
 	fun_del_ref(fun);
 	
-	log_msg(LVL_DEBUG, "devman_remove_function() succeeded.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_remove_function() succeeded.");
 	async_answer_0(callid, EOK);
 }
@@ -726,5 +726,5 @@
 	
 	initialize_running_driver(driver, &device_tree);
-	log_msg(LVL_DEBUG, "The `%s` driver was successfully initialized.",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "The `%s` driver was successfully initialized.",
 	    driver->name);
 	return 0;
@@ -742,5 +742,5 @@
 	client = async_get_client_data();
 	if (client == NULL) {
-		log_msg(LVL_ERROR, "Failed to allocate client data.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to allocate client data.");
 		return;
 	}
@@ -1229,5 +1229,5 @@
 	 */
 	if (dev == NULL) {
-		log_msg(LVL_ERROR, "IPC forwarding failed - no device or "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding failed - no device or "
 		    "function with handle %" PRIun " was found.", handle);
 		async_answer_0(iid, ENOENT);
@@ -1236,5 +1236,5 @@
 
 	if (fun == NULL && !drv_to_parent) {
-		log_msg(LVL_ERROR, NAME ": devman_forward error - cannot "
+		log_msg(LOG_DEFAULT, LVL_ERROR, NAME ": devman_forward error - cannot "
 		    "connect to handle %" PRIun ", refers to a device.",
 		    handle);
@@ -1264,5 +1264,5 @@
 	
 	if (driver == NULL) {
-		log_msg(LVL_ERROR, "IPC forwarding refused - " \
+		log_msg(LOG_DEFAULT, LVL_ERROR, "IPC forwarding refused - " \
 		    "the device %" PRIun " is not in usable state.", handle);
 		async_answer_0(iid, ENOENT);
@@ -1277,5 +1277,5 @@
 	
 	if (!driver->sess) {
-		log_msg(LVL_ERROR,
+		log_msg(LOG_DEFAULT, LVL_ERROR,
 		    "Could not forward to driver `%s'.", driver->name);
 		async_answer_0(iid, EINVAL);
@@ -1284,9 +1284,9 @@
 
 	if (fun != NULL) {
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "Forwarding request for `%s' function to driver `%s'.",
 		    fun->pathname, driver->name);
 	} else {
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "Forwarding request for `%s' device to driver `%s'.",
 		    dev->pfun->pathname, driver->name);
@@ -1320,5 +1320,5 @@
 	
 	if (fun == NULL || fun->dev == NULL || fun->dev->drv == NULL) {
-		log_msg(LVL_WARN, "devman_connection_loc(): function "
+		log_msg(LOG_DEFAULT, LVL_WARN, "devman_connection_loc(): function "
 		    "not found.\n");
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -1338,5 +1338,5 @@
 	async_exchange_end(exch);
 	
-	log_msg(LVL_DEBUG,
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
 	    "Forwarding loc service request for `%s' function to driver `%s'.",
 	    fun->pathname, driver->name);
@@ -1394,5 +1394,5 @@
 static bool devman_init(void)
 {
-	log_msg(LVL_DEBUG, "devman_init - looking for available drivers.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_init - looking for available drivers.");
 	
 	/* Initialize list of available drivers. */
@@ -1400,13 +1400,13 @@
 	if (lookup_available_drivers(&drivers_list,
 	    DRIVER_DEFAULT_STORE) == 0) {
-		log_msg(LVL_FATAL, "No drivers found.");
+		log_msg(LOG_DEFAULT, LVL_FATAL, "No drivers found.");
 		return false;
 	}
 	
-	log_msg(LVL_DEBUG, "devman_init - list of drivers has been initialized.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_init - list of drivers has been initialized.");
 	
 	/* Create root device node. */
 	if (!init_device_tree(&device_tree, &drivers_list)) {
-		log_msg(LVL_FATAL, "Failed to initialize device tree.");
+		log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to initialize device tree.");
 		return false;
 	}
@@ -1428,5 +1428,5 @@
 	printf("%s: HelenOS Device Manager\n", NAME);
 	
-	int rc = log_init(NAME, LVL_WARN);
+	int rc = log_init(NAME);
 	if (rc != EOK) {
 		printf("%s: Error initializing logging subsystem.\n", NAME);
@@ -1440,5 +1440,5 @@
 	
 	if (!devman_init()) {
-		log_msg(LVL_ERROR, "Error while initializing service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error while initializing service.");
 		return -1;
 	}
@@ -1447,5 +1447,5 @@
 	rc = service_register(SERVICE_DEVMAN);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering as a service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering as a service.");
 		return rc;
 	}
Index: uspace/srv/fs/udf/udf.c
===================================================================
--- uspace/srv/fs/udf/udf.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/fs/udf/udf.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -61,6 +61,6 @@
 int main(int argc, char *argv[])
 {
-	log_init(NAME, LVL_NOTE);
-	log_msg(LVL_NOTE, "HelenOS UDF 1.02 file system server");
+	log_init(NAME);
+	log_msg(LOG_DEFAULT, LVL_NOTE, "HelenOS UDF 1.02 file system server");
 	
 	if (argc == 3) {
@@ -68,5 +68,5 @@
 			udf_vfs_info.instance = strtol(argv[2], NULL, 10);
 		else {
-			log_msg(LVL_FATAL, "Unrecognized parameters");
+			log_msg(LOG_DEFAULT, LVL_FATAL, "Unrecognized parameters");
 			return 1;
 		}
@@ -76,5 +76,5 @@
 	    service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_VFS, 0, 0);
 	if (!vfs_sess) {
-		log_msg(LVL_FATAL, "Failed to connect to VFS");
+		log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to connect to VFS");
 		return 2;
 	}
@@ -89,5 +89,5 @@
 		goto err;
 	
-	log_msg(LVL_NOTE, "Accepting connections");
+	log_msg(LOG_DEFAULT, LVL_NOTE, "Accepting connections");
 	task_retval(0);
 	async_manager();
@@ -97,5 +97,5 @@
 	
 err:
-	log_msg(LVL_FATAL, "Failed to register file system (%d)", rc);
+	log_msg(LOG_DEFAULT, LVL_FATAL, "Failed to register file system (%d)", rc);
 	return rc;
 }
Index: uspace/srv/fs/udf/udf_file.c
===================================================================
--- uspace/srv/fs/udf/udf_file.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/fs/udf/udf_file.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -71,5 +71,5 @@
 	    FLE32(exd->extent_location.lblock_num);
 	
-	log_msg(LVL_DEBUG,
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
 	    "Extended allocator: start=%d, block_num=%d, len=%d", start,
 	    FLE32(exd->extent_location.lblock_num), FLE32(exd->info_length));
@@ -100,5 +100,5 @@
 	switch (icb_flag) {
 	case UDF_SHORT_AD:
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "ICB: sequence of allocation descriptors - icbflag = short_ad_t");
 		
@@ -167,5 +167,5 @@
 		
 	case UDF_LONG_AD:
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "ICB: sequence of allocation descriptors - icbflag = long_ad_t");
 		
@@ -203,10 +203,10 @@
 		
 	case UDF_EXTENDED_AD:
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "ICB: sequence of allocation descriptors - icbflag = extended_ad_t");
 		break;
 		
 	case UDF_DATA_AD:
-		log_msg(LVL_DEBUG,
+		log_msg(LOG_DEFAULT, LVL_DEBUG,
 		    "ICB: sequence of allocation descriptors - icbflag = 3, node contains data itself");
 		
@@ -253,5 +253,5 @@
 		switch (FLE16(data->id)) {
 		case UDF_FILE_ENTRY:
-			log_msg(LVL_DEBUG, "ICB: File entry descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: File entry descriptor found");
 			
 			udf_file_entry_descriptor_t *file =
@@ -267,5 +267,5 @@
 			
 		case UDF_EFILE_ENTRY:
-			log_msg(LVL_DEBUG, "ICB: Extended file entry descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Extended file entry descriptor found");
 			
 			udf_extended_file_entry_descriptor_t *efile =
@@ -281,5 +281,5 @@
 			
 		case UDF_ICB_TERMINAL:
-			log_msg(LVL_DEBUG, "ICB: Terminal entry descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Terminal entry descriptor found");
 			block_put(block);
 			return EOK;
Index: uspace/srv/fs/udf/udf_ops.c
===================================================================
--- uspace/srv/fs/udf/udf_ops.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/fs/udf/udf_ops.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -311,5 +311,5 @@
 	rc = udf_volume_recongnition(service_id);
 	if (rc != EOK) {
-		log_msg(LVL_NOTE, "VRS failed");
+		log_msg(LOG_DEFAULT, LVL_NOTE, "VRS failed");
 		fs_instance_destroy(service_id);
 		free(instance);
@@ -322,5 +322,5 @@
 	rc = udf_get_anchor_volume_descriptor(service_id, &avd);
 	if (rc != EOK) {
-		log_msg(LVL_NOTE, "Anchor read failed");
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Anchor read failed");
 		fs_instance_destroy(service_id);
 		free(instance);
@@ -329,12 +329,12 @@
 	}
 	
-	log_msg(LVL_DEBUG,
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
 	    "Volume: Anchor volume descriptor found. Sector size=%" PRIu32,
 	    instance->sector_size);
-	log_msg(LVL_DEBUG,
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
 	    "Anchor: main sequence [length=%" PRIu32 " (bytes), start=%"
 	    PRIu32 " (sector)]", avd.main_extent.length,
 	    avd.main_extent.location);
-	log_msg(LVL_DEBUG,
+	log_msg(LOG_DEFAULT, LVL_DEBUG,
 	    "Anchor: reserve sequence [length=%" PRIu32 " (bytes), start=%"
 	    PRIu32 " (sector)]", avd.reserve_extent.length,
@@ -353,5 +353,5 @@
 	rc = udf_read_volume_descriptor_sequence(service_id, avd.main_extent);
 	if (rc != EOK) {
-		log_msg(LVL_NOTE, "Volume Descriptor Sequence read failed");
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Volume Descriptor Sequence read failed");
 		fs_instance_destroy(service_id);
 		free(instance);
@@ -364,5 +364,5 @@
 	rc = udf_node_get(&rfn, service_id, instance->volumes[DEFAULT_VOL].root_dir);
 	if (rc != EOK) {
-		log_msg(LVL_NOTE, "Can't create root node");
+		log_msg(LOG_DEFAULT, LVL_NOTE, "Can't create root node");
 		fs_instance_destroy(service_id);
 		free(instance);
Index: uspace/srv/fs/udf/udf_volume.c
===================================================================
--- uspace/srv/fs/udf/udf_volume.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/fs/udf/udf_volume.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -63,5 +63,5 @@
 fs_index_t udf_long_ad_to_pos(udf_instance_t *instance, udf_long_ad_t *long_ad)
 {
-	log_msg(LVL_DEBUG, "Long_Ad to Pos: "
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Long_Ad to Pos: "
 	    "partition_num=%" PRIu16 ", partition_block=%" PRIu32,
 	    FLE16(long_ad->location.partition_num),
@@ -130,10 +130,10 @@
 		    (str_lcmp(VRS_NSR3, (char *) vd->identifier, VRS_ID_LEN) == 0)) {
 			nsr_found = true;
-			log_msg(LVL_DEBUG, "VRS: NSR found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "VRS: NSR found");
 			continue;
 		}
 		
 		if (str_lcmp(VRS_END, (char *) vd->identifier, VRS_ID_LEN) == 0) {
-			log_msg(LVL_DEBUG, "VRS: end found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "VRS: end found");
 			break;
 		}
@@ -382,5 +382,5 @@
 	switch (FLE16(desc->id)) {
 	case UDF_FILE_ENTRY:
-		log_msg(LVL_DEBUG, "ICB: File entry descriptor found");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: File entry descriptor found");
 		
 		udf_file_entry_descriptor_t *fed =
@@ -394,5 +394,5 @@
 		
 	case UDF_EFILE_ENTRY:
-		log_msg(LVL_DEBUG, "ICB: Extended file entry descriptor found");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "ICB: Extended file entry descriptor found");
 		
 		udf_extended_file_entry_descriptor_t *efed =
@@ -514,5 +514,5 @@
 				    &instance->partitions[j];
 				
-				log_msg(LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
 				    "found and filled", i, pm1->partition_map_type);
 				
@@ -531,5 +531,5 @@
 				    (udf_metadata_partition_map_t *) idx;
 				
-				log_msg(LVL_DEBUG, "Metadata file location=%u",
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "Metadata file location=%u",
 				    FLE32(metadata->metadata_fileloc));
 				
@@ -569,8 +569,8 @@
 				    &instance->partitions[j];
 				
-				log_msg(LVL_DEBUG, "Virtual partition: num=%d, start=%d",
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "Virtual partition: num=%d, start=%d",
 				    instance->partitions[j].number,
 				    instance->partitions[j].start);
-				log_msg(LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
 				    "found and filled", i, pm2->partition_map_type);
 				
@@ -583,5 +583,5 @@
 			udf_general_type_t *pm = (udf_general_type_t *) idx;
 			
-			log_msg(LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume[%" PRIun "]: partition [type %u] "
 			    "found and skipped", i, pm->partition_map_type);
 			
@@ -657,5 +657,5 @@
 		/* One sector size descriptors */
 		case UDF_TAG_PVD:
-			log_msg(LVL_DEBUG, "Volume: Primary volume descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Primary volume descriptor found");
 			
 			if (!udf_check_prevailing_pvd(pvd, pvd_cnt, &vol->volume)) {
@@ -669,10 +669,10 @@
 			
 		case UDF_TAG_VDP:
-			log_msg(LVL_DEBUG, "Volume: Volume descriptor pointer found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Volume descriptor pointer found");
 			pos++;
 			break;
 			
 		case UDF_TAG_IUVD:
-			log_msg(LVL_DEBUG,
+			log_msg(LOG_DEFAULT, LVL_DEBUG,
 			    "Volume: Implementation use volume descriptor found");
 			pos++;
@@ -680,9 +680,9 @@
 			
 		case UDF_TAG_PD:
-			log_msg(LVL_DEBUG, "Volume: Partition descriptor found");
-			log_msg(LVL_DEBUG, "Partition number: %u, contents: '%.6s', "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Partition descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Partition number: %u, contents: '%.6s', "
 			    "access type: %" PRIu32, FLE16(vol->partition.number),
 			    vol->partition.contents.id, FLE32(vol->partition.access_type));
-			log_msg(LVL_DEBUG, "Partition start: %" PRIu32 " (sector), "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Partition start: %" PRIu32 " (sector), "
 			    "size: %" PRIu32 " (sectors)",
 			    FLE32(vol->partition.starting_location),
@@ -698,5 +698,5 @@
 			    (udf_partition_header_descriptor_t *) vol->partition.contents_use;
 			if (FLE32(phd->unallocated_space_table.length)) {
-				log_msg(LVL_DEBUG,
+				log_msg(LOG_DEFAULT, LVL_DEBUG,
 				    "space table: length=%" PRIu32 ", pos=%" PRIu32,
 				    FLE32(phd->unallocated_space_table.length),
@@ -712,5 +712,5 @@
 			
 			if (FLE32(phd->unallocated_space_bitmap.length)) {
-				log_msg(LVL_DEBUG,
+				log_msg(LOG_DEFAULT, LVL_DEBUG,
 				    "space bitmap: length=%" PRIu32 ", pos=%" PRIu32,
 				    FLE32(phd->unallocated_space_bitmap.length),
@@ -730,5 +730,5 @@
 		/* Relative size descriptors */
 		case UDF_TAG_LVD:
-			log_msg(LVL_DEBUG, "Volume: Logical volume descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Logical volume descriptor found");
 			
 			aoff64_t sct =
@@ -743,8 +743,8 @@
 			    &vol->logical.charset);
 			
-			log_msg(LVL_DEBUG, "Logical Volume ID: '%s', "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Logical Volume ID: '%s', "
 			    "logical block size: %" PRIu32 " (bytes)", tmp,
 			    FLE32(vol->logical.logical_block_size));
-			log_msg(LVL_DEBUG, "Map table size: %" PRIu32 " (bytes), "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Map table size: %" PRIu32 " (bytes), "
 			    "number of partition maps: %" PRIu32,
 			    FLE32(vol->logical.map_table_length),
@@ -761,5 +761,5 @@
 			
 		case UDF_TAG_USD:
-			log_msg(LVL_DEBUG, "Volume: Unallocated space descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Unallocated space descriptor found");
 			
 			sct = ALL_UP((sizeof(udf_unallocated_space_descriptor_t) +
@@ -780,5 +780,5 @@
 			
 		case UDF_TAG_LVID:
-			log_msg(LVL_DEBUG,
+			log_msg(LOG_DEFAULT, LVL_DEBUG,
 			    "Volume: Logical volume integrity descriptor found");
 			
@@ -787,5 +787,5 @@
 			
 		case UDF_TAG_TD:
-			log_msg(LVL_DEBUG, "Volume: Terminating descriptor found");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Volume: Terminating descriptor found");
 			
 			/* Found terminating descriptor. Exiting */
@@ -823,5 +823,5 @@
 		udf_descriptor_tag_t *desc = block->data;
 		
-		log_msg(LVL_DEBUG, "First tag ID=%" PRIu16, desc->id);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "First tag ID=%" PRIu16, desc->id);
 		
 		if (desc->checksum != udf_tag_checksum((uint8_t *) desc)) {
Index: uspace/srv/logger/Makefile
===================================================================
--- uspace/srv/logger/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/Makefile	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2012 Vojtech Horky
+# 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 = ../..
+BINARY = logger
+STATIC_NEEDED = y
+
+SOURCES = \
+	ctl.c \
+	initlvl.c \
+	level.c \
+	logs.c \
+	main.c \
+	writer.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/logger/ctl.c
===================================================================
--- uspace/srv/logger/ctl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/ctl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger
+ * @{
+ */
+
+/** @file
+ */
+
+#include <unistd.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <errno.h>
+#include <io/logctl.h>
+#include <ipc/logger.h>
+#include "logger.h"
+
+static int handle_log_level_change(sysarg_t new_level)
+{
+	void *full_name;
+	int rc = async_data_write_accept(&full_name, true, 0, 0, 0, NULL);
+	if (rc != EOK) {
+		return rc;
+	}
+
+	logger_log_t *log = find_log_by_name_and_lock(full_name);
+	free(full_name);
+	if (log == NULL)
+		return ENOENT;
+
+	log->logged_level = new_level;
+
+	log_unlock(log);
+
+	return EOK;
+}
+
+void logger_connection_handler_control(ipc_callid_t callid)
+{
+	async_answer_0(callid, EOK);
+	logger_log("control: new client.\n");
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		if (!IPC_GET_IMETHOD(call))
+			break;
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case LOGGER_CONTROL_SET_DEFAULT_LEVEL: {
+			int rc = set_default_logging_level(IPC_GET_ARG1(call));
+			async_answer_0(callid, rc);
+			break;
+		}
+		case LOGGER_CONTROL_SET_LOG_LEVEL: {
+			int rc = handle_log_level_change(IPC_GET_ARG1(call));
+			async_answer_0(callid, rc);
+			break;
+		}
+		default:
+			async_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+
+	logger_log("control: client terminated.\n");
+}
+
+
+/**
+ * @}
+ */
Index: uspace/srv/logger/initlvl.c
===================================================================
--- uspace/srv/logger/initlvl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/initlvl.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger
+ * @{
+ */
+
+/** @file
+ */
+#include <errno.h>
+#include <str_error.h>
+#include <sysinfo.h>
+#include <str.h>
+#include "logger.h"
+
+static void parse_single_level_setting(char *setting)
+{
+	char *tmp;
+	char *key = strtok_r(setting, "=", &tmp);
+	char *value = strtok_r(NULL, "=", &tmp);
+	if (key == NULL)
+		return;
+	if (value == NULL) {
+		log_level_t level;
+		int rc = log_level_from_str(key, &level);
+		if (rc != EOK)
+			return;
+		set_default_logging_level(level);
+		return;
+	}
+
+
+	log_level_t level;
+	int rc = log_level_from_str(value, &level);
+	if (rc != EOK)
+		return;
+
+	logger_log_t *log = find_or_create_log_and_lock(key, 0);
+	if (log == NULL)
+		return;
+
+	log->logged_level = level;
+	log->ref_counter++;
+
+	log_unlock(log);
+}
+
+void parse_level_settings(char *settings)
+{
+	char *tmp;
+	char *single_setting = strtok_r(settings, " ", &tmp);
+	while (single_setting != NULL) {
+		parse_single_level_setting(single_setting);
+		single_setting = strtok_r(NULL, " ", &tmp);
+	}
+}
+
+void parse_initial_settings(void)
+{
+	size_t argument_size;
+	void *argument = sysinfo_get_data("init_args.logger", &argument_size);
+	if (argument == NULL)
+		return;
+
+	char level_str[200];
+	str_cpy(level_str, 200, (const char *) argument);
+
+	parse_level_settings(level_str);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/logger/level.c
===================================================================
--- uspace/srv/logger/level.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/level.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger
+ * @{
+ */
+
+/** @file
+ */
+
+#include <errno.h>
+#include "logger.h"
+
+log_level_t default_logging_level = LVL_NOTE;
+static FIBRIL_MUTEX_INITIALIZE(default_logging_level_guard);
+
+log_level_t get_default_logging_level(void)
+{
+	fibril_mutex_lock(&default_logging_level_guard);
+	log_level_t result = default_logging_level;
+	fibril_mutex_unlock(&default_logging_level_guard);
+	return result;
+}
+
+int set_default_logging_level(log_level_t new_level)
+{
+	if (new_level >= LVL_LIMIT)
+		return ERANGE;
+	fibril_mutex_lock(&default_logging_level_guard);
+	default_logging_level = new_level;
+	fibril_mutex_unlock(&default_logging_level_guard);
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/logger/logger.h
===================================================================
--- uspace/srv/logger/logger.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/logger.h	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger
+ * @{
+ */
+/** @file Common logger service definitions.
+ */
+
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+#include <adt/list.h>
+#include <adt/prodcons.h>
+#include <io/log.h>
+#include <async.h>
+#include <bool.h>
+#include <fibril_synch.h>
+#include <stdio.h>
+
+#define NAME "logger"
+#define LOG_LEVEL_USE_DEFAULT (LVL_LIMIT + 1)
+
+#ifdef LOGGER_LOG
+#define logger_log(fmt, ...) printf(NAME ": " fmt, ##__VA_ARGS__)
+#else
+#define logger_log(fmt, ...) (void)0
+#endif
+
+typedef struct logger_log logger_log_t;
+
+typedef struct {
+	fibril_mutex_t guard;
+	char *filename;
+	FILE *logfile;
+} logger_dest_t;
+
+struct logger_log {
+	link_t link;
+
+	size_t ref_counter;
+
+	fibril_mutex_t guard;
+
+	char *name;
+	char *full_name;
+	logger_log_t *parent;
+	log_level_t logged_level;
+	logger_dest_t *dest;
+};
+
+#define MAX_REFERENCED_LOGS_PER_CLIENT 100
+
+typedef struct {
+	size_t logs_count;
+	logger_log_t *logs[MAX_REFERENCED_LOGS_PER_CLIENT];
+} logger_registered_logs_t;
+
+logger_log_t *find_log_by_name_and_lock(const char *name);
+logger_log_t *find_or_create_log_and_lock(const char *, sysarg_t);
+logger_log_t *find_log_by_id_and_lock(sysarg_t);
+bool shall_log_message(logger_log_t *, log_level_t);
+void log_unlock(logger_log_t *);
+void write_to_log(logger_log_t *, log_level_t, const char *);
+void log_release(logger_log_t *);
+
+void registered_logs_init(logger_registered_logs_t *);
+bool register_log(logger_registered_logs_t *, logger_log_t *);
+void unregister_logs(logger_registered_logs_t *);
+
+log_level_t get_default_logging_level(void);
+int set_default_logging_level(log_level_t);
+
+
+void logger_connection_handler_control(ipc_callid_t);
+void logger_connection_handler_writer(ipc_callid_t);
+
+void parse_initial_settings(void);
+void parse_level_settings(char *);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/logger/logs.c
===================================================================
--- uspace/srv/logger/logs.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/logs.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger
+ * @{
+ */
+#include <assert.h>
+#include <malloc.h>
+#include <str.h>
+#include <stdio.h>
+#include <errno.h>
+#include "logger.h"
+
+
+static FIBRIL_MUTEX_INITIALIZE(log_list_guard);
+static LIST_INITIALIZE(log_list);
+
+
+static logger_log_t *find_log_by_name_and_parent_no_list_lock(const char *name, logger_log_t *parent)
+{
+	list_foreach(log_list, it) {
+		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+		if ((parent == log->parent) && (str_cmp(log->name, name) == 0))
+			return log;
+	}
+
+	return NULL;
+}
+
+static int create_dest(const char *name, logger_dest_t **dest)
+{
+	logger_dest_t *result = malloc(sizeof(logger_dest_t));
+	if (result == NULL)
+		return ENOMEM;
+	int rc = asprintf(&result->filename, "/log/%s", name);
+	if (rc < 0) {
+		free(result);
+		return ENOMEM;
+	}
+	result->logfile = NULL;
+	fibril_mutex_initialize(&result->guard);
+	*dest = result;
+	return EOK;
+}
+
+static logger_log_t *create_log_no_locking(const char *name, logger_log_t *parent)
+{
+	logger_log_t *result = calloc(1, sizeof(logger_log_t));
+	if (result == NULL)
+		return NULL;
+
+	result->name = str_dup(name);
+	if (result->name == NULL)
+		goto error;
+
+	/*
+	 * Notice that we create new dest as the last
+	 * operation that can fail and thus there is no code
+	 * to deallocate dest.
+	 */
+	if (parent == NULL) {
+		result->full_name = str_dup(name);
+		if (result->full_name == NULL)
+			goto error;
+		int rc = create_dest(name, &result->dest);
+		if (rc != EOK)
+			goto error;
+	} else {
+		int rc = asprintf(&result->full_name, "%s/%s",
+		    parent->full_name, name);
+		if (rc < 0)
+			goto error;
+		result->dest = parent->dest;
+	}
+
+	/* Following initializations cannot fail. */
+	result->logged_level = LOG_LEVEL_USE_DEFAULT;
+	fibril_mutex_initialize(&result->guard);
+	link_initialize(&result->link);
+	result->parent = parent;
+
+	return result;
+
+error:
+	free(result->name);
+	free(result->full_name);
+	free(result);
+	return NULL;
+
+}
+
+logger_log_t *find_or_create_log_and_lock(const char *name, sysarg_t parent_id)
+{
+	logger_log_t *result = NULL;
+	logger_log_t *parent = (logger_log_t *) parent_id;
+
+	fibril_mutex_lock(&log_list_guard);
+
+	result = find_log_by_name_and_parent_no_list_lock(name, parent);
+	if (result == NULL) {
+		result = create_log_no_locking(name, parent);
+		if (result == NULL)
+			goto leave;
+		list_append(&result->link, &log_list);
+		if (result->parent != NULL) {
+			fibril_mutex_lock(&result->parent->guard);
+			result->parent->ref_counter++;
+			fibril_mutex_unlock(&result->parent->guard);
+		}
+	}
+
+	fibril_mutex_lock(&result->guard);
+
+leave:
+	fibril_mutex_unlock(&log_list_guard);
+
+	return result;
+}
+
+logger_log_t *find_log_by_name_and_lock(const char *name)
+{
+	logger_log_t *result = NULL;
+
+	fibril_mutex_lock(&log_list_guard);
+	list_foreach(log_list, it) {
+		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+		if (str_cmp(log->full_name, name) == 0) {
+			fibril_mutex_lock(&log->guard);
+			result = log;
+			break;
+		}
+	}
+	fibril_mutex_unlock(&log_list_guard);
+
+	return result;
+}
+
+logger_log_t *find_log_by_id_and_lock(sysarg_t id)
+{
+	logger_log_t *result = NULL;
+
+	fibril_mutex_lock(&log_list_guard);
+	list_foreach(log_list, it) {
+		logger_log_t *log = list_get_instance(it, logger_log_t, link);
+		if ((sysarg_t) log == id) {
+			fibril_mutex_lock(&log->guard);
+			result = log;
+			break;
+		}
+	}
+	fibril_mutex_unlock(&log_list_guard);
+
+	return result;
+}
+
+static log_level_t get_actual_log_level(logger_log_t *log)
+{
+	/* Find recursively proper log level. */
+	if (log->logged_level == LOG_LEVEL_USE_DEFAULT) {
+		if (log->parent == NULL)
+			return get_default_logging_level();
+		else
+			return get_actual_log_level(log->parent);
+	}
+	return log->logged_level;
+}
+
+bool shall_log_message(logger_log_t *log, log_level_t level)
+{
+	fibril_mutex_lock(&log_list_guard);
+	bool result = level <= get_actual_log_level(log);
+	fibril_mutex_unlock(&log_list_guard);
+	return result;
+}
+
+void log_unlock(logger_log_t *log)
+{
+	assert(fibril_mutex_is_locked(&log->guard));
+	fibril_mutex_unlock(&log->guard);
+}
+
+/** Decreases reference counter on the log and destory the log if
+ * necessary.
+ *
+ * Precondition: log is locked.
+ *
+ * @param log Log to release from using by the caller.
+ */
+void log_release(logger_log_t *log)
+{
+	assert(fibril_mutex_is_locked(&log->guard));
+	assert(log->ref_counter > 0);
+
+	/* We are definitely not the last ones. */
+	if (log->ref_counter > 1) {
+		log->ref_counter--;
+		fibril_mutex_unlock(&log->guard);
+		return;
+	}
+
+	/*
+	 * To prevent deadlock, we need to get the list lock first.
+	 * Deadlock scenario:
+	 * Us: LOCKED(log), want to LOCK(list)
+	 * Someone else calls find_log_by_name_and_lock(log->fullname) ->
+	 *   LOCKED(list), wants to LOCK(log)
+	 */
+	fibril_mutex_unlock(&log->guard);
+
+	/* Ensuring correct locking order. */
+	fibril_mutex_lock(&log_list_guard);
+	/*
+	 * The reference must be still valid because we have not decreased
+	 * the reference counter.
+	 */
+	fibril_mutex_lock(&log->guard);
+	assert(log->ref_counter > 0);
+	log->ref_counter--;
+
+	if (log->ref_counter > 0) {
+		/*
+		 * Meanwhile, someone else increased the ref counter.
+		 * No big deal, we just return immediatelly.
+		 */
+		fibril_mutex_unlock(&log->guard);
+		fibril_mutex_unlock(&log_list_guard);
+		return;
+	}
+
+	/*
+	 * Here we are on a destroy path. We need to
+	 * - remove ourselves from the list
+	 * - decrease reference of the parent (if not top-level log)
+	 *   - we must do that after we relaase list lock to prevent
+	 *     deadlock with ourselves
+	 * - destroy dest (if top-level log)
+	 */
+	assert(log->ref_counter == 0);
+
+	list_remove(&log->link);
+	fibril_mutex_unlock(&log_list_guard);
+	fibril_mutex_unlock(&log->guard);
+
+	if (log->parent == NULL) {
+		fclose(log->dest->logfile);
+		free(log->dest->filename);
+		free(log->dest);
+	} else {
+		fibril_mutex_lock(&log->parent->guard);
+		log_release(log->parent);
+	}
+
+	logger_log("Destroyed log %s.\n", log->full_name);
+
+	free(log->name);
+	free(log->full_name);
+
+	free(log);
+}
+
+
+void write_to_log(logger_log_t *log, log_level_t level, const char *message)
+{
+	assert(fibril_mutex_is_locked(&log->guard));
+	assert(log->dest != NULL);
+	fibril_mutex_lock(&log->dest->guard);
+	if (log->dest->logfile == NULL)
+		log->dest->logfile = fopen(log->dest->filename, "a");
+
+	if (log->dest->logfile != NULL) {
+		fprintf(log->dest->logfile, "[%s] %s: %s\n",
+		    log->full_name, log_level_str(level),
+		    (const char *) message);
+		fflush(log->dest->logfile);
+	}
+
+	fibril_mutex_unlock(&log->dest->guard);
+}
+
+void registered_logs_init(logger_registered_logs_t *logs)
+{
+	logs->logs_count = 0;
+}
+
+bool register_log(logger_registered_logs_t *logs, logger_log_t *new_log)
+{
+	if (logs->logs_count >= MAX_REFERENCED_LOGS_PER_CLIENT) {
+		return false;
+	}
+
+	assert(fibril_mutex_is_locked(&new_log->guard));
+	new_log->ref_counter++;
+
+	logs->logs[logs->logs_count] = new_log;
+	logs->logs_count++;
+
+	return true;
+}
+
+void unregister_logs(logger_registered_logs_t *logs)
+{
+	for (size_t i = 0; i < logs->logs_count; i++) {
+		logger_log_t *log = logs->logs[i];
+		fibril_mutex_lock(&log->guard);
+		log_release(log);
+	}
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/logger/main.c
===================================================================
--- uspace/srv/logger/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/main.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger Logging service.
+ * @brief HelenOS logging service.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <ipc/services.h>
+#include <ipc/logger.h>
+#include <io/log.h>
+#include <io/logctl.h>
+#include <ns.h>
+#include <async.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <malloc.h>
+#include "logger.h"
+
+static void connection_handler(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	logger_interface_t iface = IPC_GET_ARG1(*icall);
+
+	switch (iface) {
+	case LOGGER_INTERFACE_CONTROL:
+		logger_connection_handler_control(iid);
+		break;
+	case LOGGER_INTERFACE_WRITER:
+		logger_connection_handler_writer(iid);
+		break;
+	default:
+		async_answer_0(iid, EINVAL);
+		break;
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": HelenOS Logging Service\n");
+	
+	parse_initial_settings();
+	for (int i = 1; i < argc; i++) {
+		parse_level_settings(argv[i]);
+	}
+
+	async_set_client_connection(connection_handler);
+	
+	int rc = service_register(SERVICE_LOGGER);
+	if (rc != EOK) {
+		printf(NAME ": failed to register: %s.\n", str_error(rc));
+		return -1;
+	}
+	
+	printf(NAME ": Accepting connections\n");
+	async_manager();
+	
+	/* Never reached */
+	return 0;
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/logger/writer.c
===================================================================
--- uspace/srv/logger/writer.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
+++ uspace/srv/logger/writer.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012 Vojtech Horky
+ * 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 logger Logging service.
+ * @brief HelenOS logging service.
+ * @{
+ */
+
+/** @file
+ */
+
+#include <ipc/services.h>
+#include <ipc/logger.h>
+#include <io/log.h>
+#include <io/logctl.h>
+#include <ns.h>
+#include <async.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+#include <malloc.h>
+#include "logger.h"
+
+
+static logger_log_t *handle_create_log(sysarg_t parent)
+{
+	void *name;
+	int rc = async_data_write_accept(&name, true, 1, 0, 0, NULL);
+	if (rc != EOK)
+		return NULL;
+
+	logger_log_t *log = find_or_create_log_and_lock(name, parent);
+
+	free(name);
+
+	return log;
+}
+
+static int handle_receive_message(sysarg_t log_id, sysarg_t level)
+{
+	logger_log_t *log = find_log_by_id_and_lock(log_id);
+	if (log == NULL)
+		return ENOENT;
+
+	void *message = NULL;
+	int rc = async_data_write_accept(&message, true, 1, 0, 0, NULL);
+	if (rc != EOK)
+		goto leave;
+
+	if (!shall_log_message(log, level)) {
+		rc = EOK;
+		goto leave;
+	}
+
+	printf("[%s] %s: %s\n",
+	    log->full_name, log_level_str(level),
+	    (const char *) message);
+	write_to_log(log, level, message);
+
+	rc = EOK;
+
+leave:
+	log_unlock(log);
+	free(message);
+
+	return rc;
+}
+
+void logger_connection_handler_writer(ipc_callid_t callid)
+{
+	/* Acknowledge the connection. */
+	async_answer_0(callid, EOK);
+
+	logger_log("writer: new client.\n");
+
+	logger_registered_logs_t registered_logs;
+	registered_logs_init(&registered_logs);
+
+	while (true) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+
+		if (!IPC_GET_IMETHOD(call))
+			break;
+
+		switch (IPC_GET_IMETHOD(call)) {
+		case LOGGER_WRITER_CREATE_LOG: {
+			logger_log_t *log = handle_create_log(IPC_GET_ARG1(call));
+			if (log == NULL) {
+				async_answer_0(callid, ENOMEM);
+				break;
+			}
+			if (!register_log(&registered_logs, log)) {
+				log_unlock(log);
+				async_answer_0(callid, ELIMIT);
+				break;
+			}
+			log_unlock(log);
+			async_answer_1(callid, EOK, (sysarg_t) log);
+			break;
+		}
+		case LOGGER_WRITER_MESSAGE: {
+			int rc = handle_receive_message(IPC_GET_ARG1(call),
+			    IPC_GET_ARG2(call));
+			async_answer_0(callid, rc);
+			break;
+		}
+		default:
+			async_answer_0(callid, EINVAL);
+			break;
+		}
+	}
+
+	unregister_logs(&registered_logs);
+	logger_log("writer: client terminated.\n");
+}
+
+
+/**
+ * @}
+ */
Index: uspace/srv/net/ethip/arp.c
===================================================================
--- uspace/srv/net/ethip/arp.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/ethip/arp.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -59,5 +59,5 @@
 	ethip_link_addr_t *laddr;
 
-	log_msg(LVL_DEBUG, "arp_received()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_received()");
 
 	rc = arp_pdu_decode(frame->data, frame->size, &packet);
@@ -65,10 +65,10 @@
 		return;
 
-	log_msg(LVL_DEBUG, "ARP PDU decoded, opcode=%d, tpa=%x",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ARP PDU decoded, opcode=%d, tpa=%x",
 	    packet.opcode, packet.target_proto_addr.ipv4);
 
 	laddr = ethip_nic_addr_find(nic, &packet.target_proto_addr);
 	if (laddr != NULL) {
-		log_msg(LVL_DEBUG, "Request/reply to my address");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Request/reply to my address");
 
 		(void) atrans_add(&packet.sender_proto_addr,
@@ -122,5 +122,5 @@
 	size_t fsize;
 
-	log_msg(LVL_DEBUG, "arp_send_packet()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_send_packet()");
 
 	rc = arp_pdu_encode(packet, &pdata, &psize);
Index: uspace/srv/net/ethip/ethip.c
===================================================================
--- uspace/srv/net/ethip/ethip.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/ethip/ethip.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -77,5 +77,5 @@
 	int rc = loc_server_register(NAME);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering server.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
 		return rc;
 	}
@@ -96,5 +96,5 @@
 	char *svc_name = NULL;
 
-	log_msg(LVL_DEBUG, "ethip_iplink_init()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_iplink_init()");
 
 	iplink_srv_init(&nic->iplink);
@@ -104,5 +104,5 @@
 	rc = asprintf(&svc_name, "net/eth%u", ++link_num);
 	if (rc < 0) {
-		log_msg(LVL_ERROR, "Out of memory.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory.");
 		goto error;
 	}
@@ -110,5 +110,5 @@
 	rc = loc_service_register(svc_name, &sid);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service %s.", svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service %s.", svc_name);
 		goto error;
 	}
@@ -118,5 +118,5 @@
 	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
 		goto error;
 	}
@@ -124,5 +124,5 @@
 	rc = loc_service_add_to_cat(sid, iplink_cat);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed adding %s to category.", svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding %s to category.", svc_name);
 		goto error;
 	}
@@ -142,8 +142,8 @@
 
 	sid = (service_id_t)IPC_GET_ARG1(*icall);
-	log_msg(LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
 	nic = ethip_nic_find_by_iplink_sid(sid);
 	if (nic == NULL) {
-		log_msg(LVL_WARN, "Uknown service ID.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Uknown service ID.");
 		return;
 	}
@@ -154,5 +154,5 @@
 static int ethip_open(iplink_srv_t *srv)
 {
-	log_msg(LVL_DEBUG, "ethip_open()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_open()");
 	return EOK;
 }
@@ -160,5 +160,5 @@
 static int ethip_close(iplink_srv_t *srv)
 {
-	log_msg(LVL_DEBUG, "ethip_close()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_close()");
 	return EOK;
 }
@@ -173,9 +173,9 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "ethip_send()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_send()");
 
 	rc = arp_translate(nic, &sdu->lsrc, &sdu->ldest, &dest_mac_addr);
 	if (rc != EOK) {
-		log_msg(LVL_WARN, "Failed to look up IP address 0x%" PRIx32,
+		log_msg(LOG_DEFAULT, LVL_WARN, "Failed to look up IP address 0x%" PRIx32,
 		    sdu->ldest.ipv4);
 		return rc;
@@ -200,5 +200,5 @@
 int ethip_received(iplink_srv_t *srv, void *data, size_t size)
 {
-	log_msg(LVL_DEBUG, "ethip_received(): srv=%p", srv);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_received(): srv=%p", srv);
 	ethip_nic_t *nic = (ethip_nic_t *)srv->arg;
 	eth_frame_t frame;
@@ -206,10 +206,10 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "ethip_received()");
-
-	log_msg(LVL_DEBUG, " - eth_pdu_decode");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_received()");
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - eth_pdu_decode");
 	rc = eth_pdu_decode(data, size, &frame);
 	if (rc != EOK) {
-		log_msg(LVL_DEBUG, " - eth_pdu_decode failed");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, " - eth_pdu_decode failed");
 		return rc;
 	}
@@ -220,14 +220,14 @@
 		break;
 	case ETYPE_IP:
-		log_msg(LVL_DEBUG, " - construct SDU");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, " - construct SDU");
 		sdu.lsrc.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 1;
 		sdu.ldest.ipv4 = (192 << 24) | (168 << 16) | (0 << 8) | 4;
 		sdu.data = frame.data;
 		sdu.size = frame.size;
-		log_msg(LVL_DEBUG, " - call iplink_ev_recv");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, " - call iplink_ev_recv");
 		rc = iplink_ev_recv(&nic->iplink, &sdu);
 		break;
 	default:
-		log_msg(LVL_DEBUG, "Unknown ethertype 0x%" PRIx16,
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ethertype 0x%" PRIx16,
 		    frame.etype_len);
 	}
@@ -239,5 +239,5 @@
 static int ethip_get_mtu(iplink_srv_t *srv, size_t *mtu)
 {
-	log_msg(LVL_DEBUG, "ethip_get_mtu()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_get_mtu()");
 	*mtu = 1500;
 	return EOK;
@@ -248,5 +248,5 @@
 	ethip_nic_t *nic = (ethip_nic_t *)srv->arg;
 
-	log_msg(LVL_DEBUG, "ethip_addr_add(0x%" PRIx32 ")", addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_addr_add(0x%" PRIx32 ")", addr->ipv4);
 	return ethip_nic_addr_add(nic, addr);
 }
@@ -256,5 +256,5 @@
 	ethip_nic_t *nic = (ethip_nic_t *)srv->arg;
 
-	log_msg(LVL_DEBUG, "ethip_addr_remove(0x%" PRIx32 ")", addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_addr_remove(0x%" PRIx32 ")", addr->ipv4);
 	return ethip_nic_addr_add(nic, addr);
 }
@@ -266,5 +266,5 @@
 	printf(NAME ": HelenOS IP over Ethernet service\n");
 
-	if (log_init(NAME, LVL_WARN) != EOK) {
+	if (log_init(NAME) != EOK) {
 		printf(NAME ": Failed to initialize logging.\n");
 		return 1;
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -68,5 +68,5 @@
 	rc = loc_category_get_id("nic", &iplink_cat, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed resolving category 'nic'.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'nic'.");
 		fibril_mutex_unlock(&ethip_discovery_lock);
 		return ENOENT;
@@ -75,5 +75,5 @@
 	rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting list of IP links.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting list of IP links.");
 		fibril_mutex_unlock(&ethip_discovery_lock);
 		return EIO;
@@ -93,9 +93,9 @@
 
 		if (!already_known) {
-			log_msg(LVL_DEBUG, "Found NIC '%lu'",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Found NIC '%lu'",
 			    (unsigned long) svcs[i]);
 			rc = ethip_nic_open(svcs[i]);
 			if (rc != EOK)
-				log_msg(LVL_ERROR, "Could not open NIC.");
+				log_msg(LOG_DEFAULT, LVL_ERROR, "Could not open NIC.");
 		}
 	}
@@ -110,5 +110,5 @@
 
 	if (nic == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating NIC structure. "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC structure. "
 		    "Out of memory.");
 		return NULL;
@@ -126,5 +126,5 @@
 
 	if (laddr == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating NIC address structure. "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating NIC address structure. "
 		    "Out of memory.");
 		return NULL;
@@ -153,5 +153,5 @@
 	nic_address_t nic_address;
 	
-	log_msg(LVL_DEBUG, "ethip_nic_open()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_open()");
 	ethip_nic_t *nic = ethip_nic_new();
 	if (nic == NULL)
@@ -160,5 +160,5 @@
 	int rc = loc_service_get_name(sid, &nic->svc_name);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting service name.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting service name.");
 		goto error;
 	}
@@ -166,5 +166,5 @@
 	nic->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
 	if (nic->sess == NULL) {
-		log_msg(LVL_ERROR, "Failed connecting '%s'", nic->svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting '%s'", nic->svc_name);
 		goto error;
 	}
@@ -174,10 +174,10 @@
 	rc = nic_callback_create(nic->sess, ethip_nic_cb_conn, nic);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed creating callback connection "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed creating callback connection "
 		    "from '%s'", nic->svc_name);
 		goto error;
 	}
 
-	log_msg(LVL_DEBUG, "Opened NIC '%s'", nic->svc_name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened NIC '%s'", nic->svc_name);
 	list_append(&nic->nic_list, &ethip_nic_list);
 	in_list = true;
@@ -189,5 +189,5 @@
 	rc = nic_get_address(nic->sess, &nic_address);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Error getting MAC address of NIC '%s'.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting MAC address of NIC '%s'.",
 		    nic->svc_name);
 		goto error;
@@ -198,10 +198,10 @@
 	rc = nic_set_state(nic->sess, NIC_STATE_ACTIVE);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Error activating NIC '%s'.",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Error activating NIC '%s'.",
 		    nic->svc_name);
 		goto error;
 	}
 
-	log_msg(LVL_DEBUG, "Initialized IP link service, MAC = 0x%" PRIx64,
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Initialized IP link service, MAC = 0x%" PRIx64,
 	    nic->mac_addr.addr);
 
@@ -225,5 +225,5 @@
     ipc_call_t *call)
 {
-	log_msg(LVL_DEBUG, "ethip_nic_addr_changed()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_changed()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -236,21 +236,21 @@
 	size_t size;
 
-	log_msg(LVL_DEBUG, "ethip_nic_received() nic=%p", nic);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_received() nic=%p", nic);
 
 	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
 	if (rc != EOK) {
-		log_msg(LVL_DEBUG, "data_write_accept() failed");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "data_write_accept() failed");
 		return;
 	}
 
-	log_msg(LVL_DEBUG, "Ethernet PDU contents (%zu bytes)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Ethernet PDU contents (%zu bytes)",
 	    size);
 
-	log_msg(LVL_DEBUG, "call ethip_received");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "call ethip_received");
 	rc = ethip_received(&nic->iplink, data, size);
-	log_msg(LVL_DEBUG, "free data");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "free data");
 	free(data);
 
-	log_msg(LVL_DEBUG, "ethip_nic_received() done, rc=%d", rc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_received() done, rc=%d", rc);
 	async_answer_0(callid, rc);
 }
@@ -259,5 +259,5 @@
     ipc_call_t *call)
 {
-	log_msg(LVL_DEBUG, "ethip_nic_device_state()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_device_state()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -267,5 +267,5 @@
 	ethip_nic_t *nic = (ethip_nic_t *)arg;
 
-	log_msg(LVL_DEBUG, "ethnip_nic_cb_conn()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethnip_nic_cb_conn()");
 
 	while (true) {
@@ -298,5 +298,5 @@
 	int rc = loc_register_cat_change_cb(ethip_nic_cat_change_cb);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering callback for NIC "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering callback for NIC "
 		    "discovery (%d).", rc);
 		return rc;
@@ -308,19 +308,19 @@
 ethip_nic_t *ethip_nic_find_by_iplink_sid(service_id_t iplink_sid)
 {
-	log_msg(LVL_DEBUG, "ethip_nic_find_by_iplink_sid(%u)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid(%u)",
 	    (unsigned) iplink_sid);
 
 	list_foreach(ethip_nic_list, link) {
-		log_msg(LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - element");
 		ethip_nic_t *nic = list_get_instance(link, ethip_nic_t,
 		    nic_list);
 
 		if (nic->iplink_sid == iplink_sid) {
-			log_msg(LVL_DEBUG, "ethip_nic_find_by_iplink_sid - found %p", nic);
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - found %p", nic);
 			return nic;
 		}
 	}
 
-	log_msg(LVL_DEBUG, "ethip_nic_find_by_iplink_sid - not found");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_find_by_iplink_sid - not found");
 	return NULL;
 }
@@ -329,7 +329,7 @@
 {
 	int rc;
-	log_msg(LVL_DEBUG, "ethip_nic_send(size=%zu)", size);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_send(size=%zu)", size);
 	rc = nic_send_frame(nic->sess, data, size);
-	log_msg(LVL_DEBUG, "nic_send_frame -> %d", rc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "nic_send_frame -> %d", rc);
 	return rc;
 }
@@ -339,5 +339,5 @@
 	ethip_link_addr_t *laddr;
 
-	log_msg(LVL_DEBUG, "ethip_nic_addr_add()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_add()");
 	laddr = ethip_nic_addr_new(addr);
 	if (laddr == NULL)
@@ -352,5 +352,5 @@
 	ethip_link_addr_t *laddr;
 
-	log_msg(LVL_DEBUG, "ethip_nic_addr_remove()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_remove()");
 
 	laddr = ethip_nic_addr_find(nic, addr);
@@ -366,5 +366,5 @@
     iplink_srv_addr_t *addr)
 {
-	log_msg(LVL_DEBUG, "ethip_nic_addr_find()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_nic_addr_find()");
 
 	list_foreach(nic->addr_list, link) {
Index: uspace/srv/net/ethip/pdu.c
===================================================================
--- uspace/srv/net/ethip/pdu.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/ethip/pdu.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -69,8 +69,8 @@
 	    frame->size);
 
-	log_msg(LVL_DEBUG, "Encoding Ethernet frame "
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Encoding Ethernet frame "
 	    "src=%" PRIx64 " dest=%" PRIx64 " etype=%x",
 	    frame->src.addr, frame->dest.addr, frame->etype_len);
-	log_msg(LVL_DEBUG, "Encoded Ethernet frame (%zu bytes)", size);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Encoded Ethernet frame (%zu bytes)", size);
 
 	*rdata = data;
@@ -84,8 +84,8 @@
 	eth_header_t *hdr;
 
-	log_msg(LVL_DEBUG, "eth_pdu_decode()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "eth_pdu_decode()");
 
 	if (size < sizeof(eth_header_t)) {
-		log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "PDU too short (%zu)", size);
 		return EINVAL;
 	}
@@ -105,8 +105,8 @@
 	    frame->size);
 
-	log_msg(LVL_DEBUG, "Decoding Ethernet frame "
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Decoding Ethernet frame "
 	    "src=%" PRIx64 " dest=%" PRIx64 " etype=%x",
 	    frame->src.addr, frame->dest.addr, frame->etype_len);
-	log_msg(LVL_DEBUG, "Decoded Ethernet frame payload (%zu bytes)", frame->size);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Decoded Ethernet frame payload (%zu bytes)", frame->size);
 
 	return EOK;
@@ -145,5 +145,5 @@
 	uint16_t fopcode;
 
-	log_msg(LVL_DEBUG, "arp_pdu_encode()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_pdu_encode()");
 
 	size = sizeof(arp_eth_packet_fmt_t);
@@ -185,8 +185,8 @@
 	arp_eth_packet_fmt_t *pfmt;
 
-	log_msg(LVL_DEBUG, "arp_pdu_decode()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_pdu_decode()");
 
 	if (size < sizeof(arp_eth_packet_fmt_t)) {
-		log_msg(LVL_DEBUG, "ARP PDU too short (%zu)", size);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "ARP PDU too short (%zu)", size);
 		return EINVAL;
 	}
@@ -195,5 +195,5 @@
 
 	if (uint16_t_be2host(pfmt->hw_addr_space) != AHRD_ETHERNET) {
-		log_msg(LVL_DEBUG, "HW address space != %u (%" PRIu16 ")",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "HW address space != %u (%" PRIu16 ")",
 		    AHRD_ETHERNET, uint16_t_be2host(pfmt->hw_addr_space));
 		return EINVAL;
@@ -201,5 +201,5 @@
 
 	if (uint16_t_be2host(pfmt->proto_addr_space) != 0x0800) {
-		log_msg(LVL_DEBUG, "Proto address space != %u (%" PRIu16 ")",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Proto address space != %u (%" PRIu16 ")",
 		    ETYPE_IP, uint16_t_be2host(pfmt->proto_addr_space));
 		return EINVAL;
@@ -207,5 +207,5 @@
 
 	if (pfmt->hw_addr_size != ETH_ADDR_SIZE) {
-		log_msg(LVL_DEBUG, "HW address size != %zu (%zu)",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "HW address size != %zu (%zu)",
 		    (size_t)ETH_ADDR_SIZE, (size_t)pfmt->hw_addr_size);
 		return EINVAL;
@@ -213,5 +213,5 @@
 
 	if (pfmt->proto_addr_size != IPV4_ADDR_SIZE) {
-		log_msg(LVL_DEBUG, "Proto address size != %zu (%zu)",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Proto address size != %zu (%zu)",
 		    (size_t)IPV4_ADDR_SIZE, (size_t)pfmt->proto_addr_size);
 		return EINVAL;
@@ -222,5 +222,5 @@
 	case AOP_REPLY: packet->opcode = aop_reply; break;
 	default:
-		log_msg(LVL_DEBUG, "Invalid ARP opcode (%" PRIu16 ")",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Invalid ARP opcode (%" PRIu16 ")",
 		    uint16_t_be2host(pfmt->opcode));
 		return EINVAL;
@@ -233,5 +233,5 @@
 	packet->target_proto_addr.ipv4 =
 	    uint32_t_be2host(pfmt->target_proto_addr);
-	log_msg(LVL_DEBUG, "packet->tpa = %x\n", pfmt->target_proto_addr);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "packet->tpa = %x\n", pfmt->target_proto_addr);
 
 	return EOK;
Index: uspace/srv/net/inetsrv/addrobj.c
===================================================================
--- uspace/srv/net/inetsrv/addrobj.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/addrobj.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -59,5 +59,5 @@
 
 	if (addr == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating address object. "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating address object. "
 		    "Out of memory.");
 		return NULL;
@@ -114,5 +114,5 @@
 	uint32_t mask;
 
-	log_msg(LVL_DEBUG, "inet_addrobj_find(%x)", (unsigned)addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find(%x)", (unsigned)addr->ipv4);
 
 	fibril_mutex_lock(&addr_list_lock);
@@ -125,5 +125,5 @@
 		if ((naddr->naddr.ipv4 & mask) == (addr->ipv4 & mask)) {
 			fibril_mutex_unlock(&addr_list_lock);
-			log_msg(LVL_DEBUG, "inet_addrobj_find: found %p",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: found %p",
 			    naddr);
 			return naddr;
@@ -131,5 +131,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "inet_addrobj_find: Not found");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find: Not found");
 	fibril_mutex_unlock(&addr_list_lock);
 
@@ -147,5 +147,5 @@
 	assert(fibril_mutex_is_locked(&addr_list_lock));
 
-	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked('%s', '%s')",
 	    name, ilink->svc_name);
 
@@ -155,5 +155,5 @@
 
 		if (naddr->ilink == ilink && str_cmp(naddr->name, name) == 0) {
-			log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: found %p",
 			    naddr);
 			return naddr;
@@ -161,5 +161,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name_locked: Not found");
 
 	return NULL;
@@ -177,5 +177,5 @@
 	inet_addrobj_t *aobj;
 
-	log_msg(LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_find_by_name('%s', '%s')",
 	    name, ilink->svc_name);
 
@@ -194,5 +194,5 @@
 inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t id)
 {
-	log_msg(LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_addrobj_get_by_id(%zu)", (size_t)id);
 
 	fibril_mutex_lock(&addr_list_lock);
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/icmp.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -57,5 +57,5 @@
 	uint8_t type;
 
-	log_msg(LVL_DEBUG, "icmp_recv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "icmp_recv()");
 
 	if (dgram->size < 1)
@@ -84,5 +84,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "icmp_recv_echo_request()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "icmp_recv_echo_request()");
 
 	if (dgram->size < sizeof(icmp_echo_t))
@@ -124,5 +124,5 @@
 	uint16_t ident;
 
-	log_msg(LVL_DEBUG, "icmp_recv_echo_reply()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "icmp_recv_echo_reply()");
 
 	if (dgram->size < sizeof(icmp_echo_t))
Index: uspace/srv/net/inetsrv/inet_link.c
===================================================================
--- uspace/srv/net/inetsrv/inet_link.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/inet_link.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -64,14 +64,14 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inet_iplink_recv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
 	rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
 	if (rc != EOK) {
-		log_msg(LVL_DEBUG, "failed decoding PDU");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
 		return rc;
 	}
 
-	log_msg(LVL_DEBUG, "call inet_recv_packet()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
 	rc = inet_recv_packet(&packet);
-	log_msg(LVL_DEBUG, "call inet_recv_packet -> %d", rc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
 	free(packet.data);
 
@@ -91,5 +91,5 @@
 	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
 		fibril_mutex_unlock(&inet_discovery_lock);
 		return ENOENT;
@@ -98,5 +98,5 @@
 	rc = loc_category_get_svcs(iplink_cat, &svcs, &count);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting list of IP links.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting list of IP links.");
 		fibril_mutex_unlock(&inet_discovery_lock);
 		return EIO;
@@ -116,9 +116,9 @@
 
 		if (!already_known) {
-			log_msg(LVL_DEBUG, "Found IP link '%lu'",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Found IP link '%lu'",
 			    (unsigned long) svcs[i]);
 			rc = inet_link_open(svcs[i]);
 			if (rc != EOK)
-				log_msg(LVL_ERROR, "Could not open IP link.");
+				log_msg(LOG_DEFAULT, LVL_ERROR, "Could not open IP link.");
 		}
 	}
@@ -133,5 +133,5 @@
 
 	if (ilink == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating link structure. "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating link structure. "
 		    "Out of memory.");
 		return NULL;
@@ -156,5 +156,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inet_link_open()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_link_open()");
 	ilink = inet_link_new();
 	if (ilink == NULL)
@@ -166,5 +166,5 @@
 	rc = loc_service_get_name(sid, &ilink->svc_name);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed getting service name.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed getting service name.");
 		goto error;
 	}
@@ -172,5 +172,5 @@
 	ilink->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid, 0);
 	if (ilink->sess == NULL) {
-		log_msg(LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting '%s'", ilink->svc_name);
 		goto error;
 	}
@@ -178,5 +178,5 @@
 	rc = iplink_open(ilink->sess, &inet_iplink_ev_ops, &ilink->iplink);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed opening IP link '%s'",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed opening IP link '%s'",
 		    ilink->svc_name);
 		goto error;
@@ -185,10 +185,10 @@
 	rc = iplink_get_mtu(ilink->iplink, &ilink->def_mtu);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed determinning MTU of link '%s'",
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed determinning MTU of link '%s'",
 		    ilink->svc_name);
 		goto error;
 	}
 
-	log_msg(LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
 	list_append(&ilink->link_list, &inet_link_list);
 
@@ -209,5 +209,5 @@
 	rc = inet_addrobj_add(addr);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
 		inet_addrobj_delete(addr);
 		/* XXX Roll back */
@@ -218,5 +218,5 @@
 	rc = iplink_addr_add(ilink->iplink, &iaddr);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
 		inet_addrobj_remove(addr);
 		inet_addrobj_delete(addr);
@@ -245,5 +245,5 @@
 	rc = loc_register_cat_change_cb(inet_link_cat_change_cb);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering callback for IP link "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering callback for IP link "
 		    "discovery (%d).", rc);
 		return rc;
Index: uspace/srv/net/inetsrv/inetcfg.c
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/inetcfg.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -61,5 +61,5 @@
 	ilink = inet_link_get_by_id(link_id);
 	if (ilink == NULL) {
-		log_msg(LVL_DEBUG, "Link %lu not found.",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
 		    (unsigned long) link_id);
 		return ENOENT;
@@ -77,5 +77,5 @@
 	rc = inet_addrobj_add(addr);
 	if (rc != EOK) {
-		log_msg(LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
 		inet_addrobj_delete(addr);
 		return rc;
@@ -85,5 +85,5 @@
 	rc = iplink_addr_add(ilink->iplink, &iaddr);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
 		inet_addrobj_remove(addr);
 		inet_addrobj_delete(addr);
@@ -130,5 +130,5 @@
 	ilink = inet_link_get_by_id(link_id);
 	if (ilink == NULL) {
-		log_msg(LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
 		return ENOENT;
 	}
@@ -136,5 +136,5 @@
 	addr = inet_addrobj_find_by_name(name, ilink);
 	if (addr == NULL) {
-		log_msg(LVL_DEBUG, "Address '%s' not found.", name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
 		return ENOENT;
 	}
@@ -228,5 +228,5 @@
 	sroute = inet_sroute_find_by_name(name);
 	if (sroute == NULL) {
-		log_msg(LVL_DEBUG, "Static route '%s' not found.", name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
 		return ENOENT;
 	}
@@ -245,5 +245,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_addr_create_static_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
 
 	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
@@ -269,5 +269,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_addr_delete_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
 
 	addr_id = IPC_GET_ARG1(*call);
@@ -287,5 +287,5 @@
 
 	addr_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_addr_get_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
 
 	ainfo.naddr.ipv4 = 0;
@@ -321,5 +321,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_addr_get_id_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
 
 	link_id = IPC_GET_ARG1(*call);
@@ -348,5 +348,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_get_addr_list_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
 
 	if (!async_data_read_receive(&rcallid, &max_size)) {
@@ -382,5 +382,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_get_link_list_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_link_list_srv()");
 
 	if (!async_data_read_receive(&rcallid, &max_size)) {
@@ -415,5 +415,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
 
 	if (!async_data_read_receive(&rcallid, &max_size)) {
@@ -449,5 +449,5 @@
 
 	link_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_link_get_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
 
 	linfo.name = NULL;
@@ -482,5 +482,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_sroute_create_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
 
 	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
@@ -506,5 +506,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_sroute_delete_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
 
 	sroute_id = IPC_GET_ARG1(*call);
@@ -524,5 +524,5 @@
 
 	sroute_id = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inetcfg_sroute_get_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
 
 	srinfo.dest.ipv4 = 0;
@@ -557,5 +557,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
 
 	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
@@ -574,5 +574,5 @@
 void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	log_msg(LVL_DEBUG, "inet_cfg_conn()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
 
 	/* Accept the connection */
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/inetping.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -76,5 +76,5 @@
 	client = inetping_client_find(ident);
 	if (client == NULL) {
-		log_msg(LVL_DEBUG, "Unknown ICMP ident. Dropping.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping.");
 		return ENOENT;
 	}
@@ -107,5 +107,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetping_send_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()");
 
 	rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0,
@@ -133,5 +133,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetping_get_srcaddr_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_get_srcaddr_srv()");
 
 	remote.ipv4 = IPC_GET_ARG1(*call);
@@ -192,5 +192,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inetping_conn()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()");
 
 	/* Accept the connection */
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -66,5 +66,5 @@
 static int inet_init(void)
 {
-	log_msg(LVL_DEBUG, "inet_init()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_init()");
 	
 	async_set_client_connection(inet_client_conn);
@@ -72,5 +72,5 @@
 	int rc = loc_server_register(NAME);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering server (%d).", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server (%d).", rc);
 		return EEXIST;
 	}
@@ -80,5 +80,5 @@
 	    INET_PORT_DEFAULT);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
 		return EEXIST;
 	}
@@ -87,5 +87,5 @@
 	    INET_PORT_CFG);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
 		return EEXIST;
 	}
@@ -94,5 +94,5 @@
 	    INET_PORT_PING);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service (%d).", rc);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
 		return EEXIST;
 	}
@@ -108,5 +108,5 @@
     ipc_call_t *call)
 {
-	log_msg(LVL_DEBUG, "inet_callback_create_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_callback_create_srv()");
 
 	async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
@@ -143,5 +143,5 @@
 
 	if (dir->aobj == NULL) {
-		log_msg(LVL_DEBUG, "inet_send: No route to destination.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send: No route to destination.");
 		return ENOENT;
 	}
@@ -194,5 +194,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inet_get_srcaddr_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
 
 	remote.ipv4 = IPC_GET_ARG1(*call);
@@ -212,5 +212,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inet_send_srv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
 
 	dgram.src.ipv4 = IPC_GET_ARG1(*call);
@@ -238,5 +238,5 @@
 
 	proto = IPC_GET_ARG1(*call);
-	log_msg(LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
 
 	if (proto > UINT8_MAX) {
@@ -272,5 +272,5 @@
 	inet_client_t client;
 
-	log_msg(LVL_DEBUG, "inet_default_conn()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_default_conn()");
 
 	/* Accept the connection */
@@ -378,5 +378,5 @@
 	inet_client_t *client;
 
-	log_msg(LVL_DEBUG, "inet_recv_dgram_local()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_recv_dgram_local()");
 
 	/* ICMP messages are handled internally */
@@ -386,5 +386,5 @@
 	client = inet_client_find(proto);
 	if (client == NULL) {
-		log_msg(LVL_DEBUG, "No client found for protocol 0x%" PRIx8,
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "No client found for protocol 0x%" PRIx8,
 		    proto);
 		return ENOENT;
@@ -428,5 +428,5 @@
 	printf(NAME ": HelenOS Internet Protocol service\n");
 
-	if (log_init(NAME, LVL_WARN) != EOK) {
+	if (log_init(NAME) != EOK) {
 		printf(NAME ": Failed to initialize logging.\n");
 		return 1;
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/pdu.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -204,8 +204,8 @@
 	uint16_t foff;
 
-	log_msg(LVL_DEBUG, "inet_pdu_decode()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_pdu_decode()");
 
 	if (size < sizeof(ip_header_t)) {
-		log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "PDU too short (%zu)", size);
 		return EINVAL;
 	}
@@ -216,5 +216,5 @@
 	    hdr->ver_ihl);
 	if (version != 4) {
-		log_msg(LVL_DEBUG, "Version (%d) != 4", version);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Version (%d) != 4", version);
 		return EINVAL;
 	}
@@ -222,10 +222,10 @@
 	tot_len = uint16_t_be2host(hdr->tot_len);
 	if (tot_len < sizeof(ip_header_t)) {
-		log_msg(LVL_DEBUG, "Total Length too small (%zu)", tot_len);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length too small (%zu)", tot_len);
 		return EINVAL;
 	}
 
 	if (tot_len > size) {
-		log_msg(LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
 			tot_len, size);
 		return EINVAL;
@@ -256,5 +256,5 @@
 	packet->data = calloc(packet->size, 1);
 	if (packet->data == NULL) {
-		log_msg(LVL_WARN, "Out of memory.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Out of memory.");
 		return ENOMEM;
 	}
Index: uspace/srv/net/inetsrv/reass.c
===================================================================
--- uspace/srv/net/inetsrv/reass.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/reass.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -86,5 +86,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "inet_reass_queue_packet()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_reass_queue_packet()");
 
 	fibril_mutex_lock(&reass_dgram_map_lock);
@@ -95,5 +95,5 @@
 		/* Only happens when we are out of memory */
 		fibril_mutex_unlock(&reass_dgram_map_lock);
-		log_msg(LVL_DEBUG, "Allocation failed, packet dropped.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Allocation failed, packet dropped.");
 		return ENOMEM;
 	}
Index: uspace/srv/net/inetsrv/sroute.c
===================================================================
--- uspace/srv/net/inetsrv/sroute.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/inetsrv/sroute.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -57,5 +57,5 @@
 
 	if (sroute == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating static route object. "
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating static route object. "
 		    "Out of memory.");
 		return NULL;
@@ -100,5 +100,5 @@
 	inet_sroute_t *best;
 
-	log_msg(LVL_DEBUG, "inet_sroute_find(%x)", (unsigned)addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find(%x)", (unsigned)addr->ipv4);
 
 	fibril_mutex_lock(&sroute_list_lock);
@@ -117,5 +117,5 @@
 		if ((sroute->dest.ipv4 & mask) == (addr->ipv4 & mask)) {
 			fibril_mutex_unlock(&sroute_list_lock);
-			log_msg(LVL_DEBUG, "inet_sroute_find: found %p",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: found %p",
 			    sroute);
 			return sroute;
@@ -123,5 +123,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "inet_sroute_find: Not found");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find: Not found");
 	fibril_mutex_unlock(&sroute_list_lock);
 
@@ -136,5 +136,5 @@
 inet_sroute_t *inet_sroute_find_by_name(const char *name)
 {
-	log_msg(LVL_DEBUG, "inet_sroute_find_by_name('%s')",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name('%s')",
 	    name);
 
@@ -147,5 +147,5 @@
 		if (str_cmp(sroute->name, name) == 0) {
 			fibril_mutex_unlock(&sroute_list_lock);
-			log_msg(LVL_DEBUG, "inet_sroute_find_by_name: found %p",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: found %p",
 			    sroute);
 			return sroute;
@@ -153,5 +153,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "inet_sroute_find_by_name: Not found");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_find_by_name: Not found");
 	fibril_mutex_unlock(&sroute_list_lock);
 
@@ -166,5 +166,5 @@
 inet_sroute_t *inet_sroute_get_by_id(sysarg_t id)
 {
-	log_msg(LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_sroute_get_by_id(%zu)", (size_t)id);
 
 	fibril_mutex_lock(&sroute_list_lock);
Index: uspace/srv/net/loopip/loopip.c
===================================================================
--- uspace/srv/net/loopip/loopip.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/loopip/loopip.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -75,5 +75,5 @@
 {
 	while (true) {
-		log_msg(LVL_DEBUG, "loopip_recv_fibril(): Wait for one item");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_recv_fibril(): Wait for one item");
 		link_t *link = prodcons_consume(&loopip_rcv_queue);
 		rqueue_entry_t *rqe = list_get_instance(link, rqueue_entry_t, link);
@@ -96,5 +96,5 @@
 	rc = loc_server_register(NAME);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering server.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server.");
 		return rc;
 	}
@@ -108,5 +108,5 @@
 	rc = loc_service_register(svc_name, &sid);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed registering service %s.", svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service %s.", svc_name);
 		return rc;
 	}
@@ -114,5 +114,5 @@
 	rc = loc_category_get_id("iplink", &iplink_cat, IPC_FLAG_BLOCKING);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed resolving category 'iplink'.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed resolving category 'iplink'.");
 		return rc;
 	}
@@ -120,5 +120,5 @@
 	rc = loc_service_add_to_cat(sid, iplink_cat);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed adding %s to category.", svc_name);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding %s to category.", svc_name);
 		return rc;
 	}
@@ -135,5 +135,5 @@
 static void loopip_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
 {
-	log_msg(LVL_DEBUG, "loopip_client_conn()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_client_conn()");
 	iplink_conn(iid, icall, &loopip_iplink);
 }
@@ -141,5 +141,5 @@
 static int loopip_open(iplink_srv_t *srv)
 {
-	log_msg(LVL_DEBUG, "loopip_open()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_open()");
 	return EOK;
 }
@@ -147,5 +147,5 @@
 static int loopip_close(iplink_srv_t *srv)
 {
-	log_msg(LVL_DEBUG, "loopip_close()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_close()");
 	return EOK;
 }
@@ -155,5 +155,5 @@
 	rqueue_entry_t *rqe;
 
-	log_msg(LVL_DEBUG, "loopip_send()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_send()");
 
 	rqe = calloc(1, sizeof(rqueue_entry_t));
@@ -184,5 +184,5 @@
 static int loopip_get_mtu(iplink_srv_t *srv, size_t *mtu)
 {
-	log_msg(LVL_DEBUG, "loopip_get_mtu()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_get_mtu()");
 	*mtu = 1500;
 	return EOK;
@@ -191,5 +191,5 @@
 static int loopip_addr_add(iplink_srv_t *srv, iplink_srv_addr_t *addr)
 {
-	log_msg(LVL_DEBUG, "loopip_addr_add(0x%" PRIx32 ")", addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_addr_add(0x%" PRIx32 ")", addr->ipv4);
 	return EOK;
 }
@@ -197,5 +197,5 @@
 static int loopip_addr_remove(iplink_srv_t *srv, iplink_srv_addr_t *addr)
 {
-	log_msg(LVL_DEBUG, "loopip_addr_remove(0x%" PRIx32 ")", addr->ipv4);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "loopip_addr_remove(0x%" PRIx32 ")", addr->ipv4);
 	return EOK;
 }
@@ -207,5 +207,5 @@
 	printf(NAME ": HelenOS loopback IP link provider\n");
 
-	if (log_init(NAME, LVL_WARN) != EOK) {
+	if (log_init(NAME) != EOK) {
 		printf(NAME ": Failed to initialize logging.\n");
 		return 1;
Index: uspace/srv/net/tcp/conn.c
===================================================================
--- uspace/srv/net/tcp/conn.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/conn.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -164,5 +164,5 @@
 static void tcp_conn_free(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_free(%p)", conn->name, conn);
 	tcp_tqueue_fini(&conn->retransmit);
 
@@ -184,5 +184,5 @@
 void tcp_conn_addref(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG2, "%s: tcp_conn_addref(%p)", conn->name, conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_addref(%p)", conn->name, conn);
 	atomic_inc(&conn->refcnt);
 }
@@ -196,5 +196,5 @@
 void tcp_conn_delref(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG2, "%s: tcp_conn_delref(%p)", conn->name, conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "%s: tcp_conn_delref(%p)", conn->name, conn);
 
 	if (atomic_predec(&conn->refcnt) == 0)
@@ -211,5 +211,5 @@
 void tcp_conn_delete(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_delete(%p)", conn->name, conn);
 
 	assert(conn->deleted == false);
@@ -245,5 +245,5 @@
 	tcp_cstate_t old_state;
 
-	log_msg(LVL_DEBUG, "tcp_conn_state_set(%p)", conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set(%p)", conn);
 
 	old_state = conn->cstate;
@@ -253,8 +253,8 @@
 	/* Run user callback function */
 	if (conn->cstate_cb != NULL) {
-		log_msg(LVL_DEBUG, "tcp_conn_state_set() - run user CB");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - run user CB");
 		conn->cstate_cb(conn, conn->cstate_cb_arg);
 	} else {
-		log_msg(LVL_DEBUG, "tcp_conn_state_set() - no user CB");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_state_set() - no user CB");
 	}
 
@@ -293,13 +293,13 @@
 	case st_syn_received:
 	case st_established:
-		log_msg(LVL_DEBUG, "%s: FIN sent -> Fin-Wait-1", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN sent -> Fin-Wait-1", conn->name);
 		tcp_conn_state_set(conn, st_fin_wait_1);
 		break;
 	case st_close_wait:
-		log_msg(LVL_DEBUG, "%s: FIN sent -> Last-Ack", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN sent -> Last-Ack", conn->name);
 		tcp_conn_state_set(conn, st_last_ack);
 		break;
 	default:
-		log_msg(LVL_ERROR, "%s: Connection state %d", conn->name,
+		log_msg(LOG_DEFAULT, LVL_ERROR, "%s: Connection state %d", conn->name,
 		    conn->cstate);
 		assert(false);
@@ -312,5 +312,5 @@
 static bool tcp_socket_match(tcp_sock_t *sock, tcp_sock_t *patt)
 {
-	log_msg(LVL_DEBUG2, "tcp_socket_match(sock=(%x,%u), pat=(%x,%u))",
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_socket_match(sock=(%x,%u), pat=(%x,%u))",
 	    sock->addr.ipv4, sock->port, patt->addr.ipv4, patt->port);
 
@@ -323,5 +323,5 @@
 		return false;
 
-	log_msg(LVL_DEBUG2, " -> match");
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " -> match");
 
 	return true;
@@ -331,5 +331,5 @@
 static bool tcp_sockpair_match(tcp_sockpair_t *sp, tcp_sockpair_t *pattern)
 {
-	log_msg(LVL_DEBUG2, "tcp_sockpair_match(%p, %p)", sp, pattern);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_sockpair_match(%p, %p)", sp, pattern);
 
 	if (!tcp_socket_match(&sp->local, &pattern->local))
@@ -353,5 +353,5 @@
 tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
 {
-	log_msg(LVL_DEBUG, "tcp_conn_find_ref(%p)", sp);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_find_ref(%p)", sp);
 
 	fibril_mutex_lock(&conn_list_lock);
@@ -360,5 +360,5 @@
 		tcp_conn_t *conn = list_get_instance(link, tcp_conn_t, link);
 		tcp_sockpair_t *csp = &conn->ident;
-		log_msg(LVL_DEBUG2, "compare with conn (f:(%x,%u), l:(%x,%u))",
+		log_msg(LOG_DEFAULT, LVL_DEBUG2, "compare with conn (f:(%x,%u), l:(%x,%u))",
 		    csp->foreign.addr.ipv4, csp->foreign.port,
 		    csp->local.addr.ipv4, csp->local.port);
@@ -380,5 +380,5 @@
 static void tcp_conn_reset(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_reset()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_reset()", conn->name);
 	tcp_conn_state_set(conn, st_closed);
 	conn->reset = true;
@@ -398,5 +398,5 @@
 {
 	/* TODO */
-	log_msg(LVL_DEBUG, "%s: tcp_reset_signal()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_reset_signal()", conn->name);
 }
 
@@ -422,5 +422,5 @@
 		return true;
 	case st_closed:
-		log_msg(LVL_WARN, "state=%d", (int) conn->cstate);
+		log_msg(LOG_DEFAULT, LVL_WARN, "state=%d", (int) conn->cstate);
 		assert(false);
 	}
@@ -436,13 +436,13 @@
 static void tcp_conn_sa_listen(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_conn_sa_listen(%p, %p)", conn, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_sa_listen(%p, %p)", conn, seg);
 
 	if ((seg->ctrl & CTL_RST) != 0) {
-		log_msg(LVL_DEBUG, "Ignoring incoming RST.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Ignoring incoming RST.");
 		return;
 	}
 
 	if ((seg->ctrl & CTL_ACK) != 0) {
-		log_msg(LVL_DEBUG, "Incoming ACK, send acceptable RST.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Incoming ACK, send acceptable RST.");
 		tcp_reply_rst(&conn->ident, seg);
 		return;
@@ -450,9 +450,9 @@
 
 	if ((seg->ctrl & CTL_SYN) == 0) {
-		log_msg(LVL_DEBUG, "SYN not present. Ignoring segment.");
-		return;
-	}
-
-	log_msg(LVL_DEBUG, "Got SYN, sending SYN, ACK.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "SYN not present. Ignoring segment.");
+		return;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Got SYN, sending SYN, ACK.");
 
 	conn->rcv_nxt = seg->seq + 1;
@@ -460,8 +460,8 @@
 
 
-	log_msg(LVL_DEBUG, "rcv_nxt=%u", conn->rcv_nxt);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "rcv_nxt=%u", conn->rcv_nxt);
 
 	if (seg->len > 1)
-		log_msg(LVL_WARN, "SYN combined with data, ignoring data.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "SYN combined with data, ignoring data.");
 
 	/* XXX select ISS */
@@ -493,15 +493,15 @@
 static void tcp_conn_sa_syn_sent(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_conn_sa_syn_sent(%p, %p)", conn, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_sa_syn_sent(%p, %p)", conn, seg);
 
 	if ((seg->ctrl & CTL_ACK) != 0) {
-		log_msg(LVL_DEBUG, "snd_una=%u, seg.ack=%u, snd_nxt=%u",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "snd_una=%u, seg.ack=%u, snd_nxt=%u",
 		    conn->snd_una, seg->ack, conn->snd_nxt);
 		if (!seq_no_ack_acceptable(conn, seg->ack)) {
 			if ((seg->ctrl & CTL_RST) == 0) {
-				log_msg(LVL_WARN, "ACK not acceptable, send RST");
+				log_msg(LOG_DEFAULT, LVL_WARN, "ACK not acceptable, send RST");
 				tcp_reply_rst(&conn->ident, seg);
 			} else {
-				log_msg(LVL_WARN, "RST,ACK not acceptable, drop");
+				log_msg(LOG_DEFAULT, LVL_WARN, "RST,ACK not acceptable, drop");
 			}
 			return;
@@ -512,5 +512,5 @@
 		/* If we get here, we have either an acceptable ACK or no ACK */
 		if ((seg->ctrl & CTL_ACK) != 0) {
-			log_msg(LVL_DEBUG, "%s: Connection reset. -> Closed",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: Connection reset. -> Closed",
 			    conn->name);
 			/* Reset connection */
@@ -518,5 +518,5 @@
 			return;
 		} else {
-			log_msg(LVL_DEBUG, "%s: RST without ACK, drop",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: RST without ACK, drop",
 			    conn->name);
 			return;
@@ -527,5 +527,5 @@
 
 	if ((seg->ctrl & CTL_SYN) == 0) {
-		log_msg(LVL_DEBUG, "No SYN bit, ignoring segment.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "No SYN bit, ignoring segment.");
 		return;
 	}
@@ -544,5 +544,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "Sent SYN, got SYN.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Sent SYN, got SYN.");
 
 	/*
@@ -551,5 +551,5 @@
 	 * will always be accepted as new window setting.
 	 */
-	log_msg(LVL_DEBUG, "SND.WND := %" PRIu32 ", SND.WL1 := %" PRIu32 ", "
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "SND.WND := %" PRIu32 ", SND.WL1 := %" PRIu32 ", "
 	    "SND.WL2 = %" PRIu32, seg->wnd, seg->seq, seg->seq);
 	conn->snd_wnd = seg->wnd;
@@ -558,9 +558,9 @@
 
 	if (seq_no_syn_acked(conn)) {
-		log_msg(LVL_DEBUG, "%s: syn acked -> Established", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: syn acked -> Established", conn->name);
 		tcp_conn_state_set(conn, st_established);
 		tcp_tqueue_ctrl_seg(conn, CTL_ACK /* XXX */);
 	} else {
-		log_msg(LVL_DEBUG, "%s: syn not acked -> Syn-Received",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: syn not acked -> Syn-Received",
 		    conn->name);
 		tcp_conn_state_set(conn, st_syn_received);
@@ -582,9 +582,9 @@
 	tcp_segment_t *pseg;
 
-	log_msg(LVL_DEBUG, "tcp_conn_sa_seq(%p, %p)", conn, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_sa_seq(%p, %p)", conn, seg);
 
 	/* Discard unacceptable segments ("old duplicates") */
 	if (!seq_no_segment_acceptable(conn, seg)) {
-		log_msg(LVL_DEBUG, "Replying ACK to unacceptable segment.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Replying ACK to unacceptable segment.");
 		tcp_tqueue_ctrl_seg(conn, CTL_ACK);
 		tcp_segment_delete(seg);
@@ -682,5 +682,5 @@
 	assert(seq_no_in_rcv_wnd(conn, seg->seq));
 
-	log_msg(LVL_WARN, "SYN is in receive window, should send reset. XXX");
+	log_msg(LOG_DEFAULT, LVL_WARN, "SYN is in receive window, should send reset. XXX");
 
 	/*
@@ -705,5 +705,5 @@
 	if (!seq_no_ack_acceptable(conn, seg->ack)) {
 		/* ACK is not acceptable, send RST. */
-		log_msg(LVL_WARN, "Segment ACK not acceptable, sending RST.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Segment ACK not acceptable, sending RST.");
 		tcp_reply_rst(&conn->ident, seg);
 		tcp_segment_delete(seg);
@@ -711,5 +711,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "%s: SYN ACKed -> Established", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: SYN ACKed -> Established", conn->name);
 
 	tcp_conn_state_set(conn, st_established);
@@ -730,14 +730,14 @@
 static cproc_t tcp_conn_seg_proc_ack_est(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_conn_seg_proc_ack_est(%p, %p)", conn, seg);
-
-	log_msg(LVL_DEBUG, "SEG.ACK=%u, SND.UNA=%u, SND.NXT=%u",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_seg_proc_ack_est(%p, %p)", conn, seg);
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.ACK=%u, SND.UNA=%u, SND.NXT=%u",
 	    (unsigned)seg->ack, (unsigned)conn->snd_una,
 	    (unsigned)conn->snd_nxt);
 
 	if (!seq_no_ack_acceptable(conn, seg->ack)) {
-		log_msg(LVL_DEBUG, "ACK not acceptable.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "ACK not acceptable.");
 		if (!seq_no_ack_duplicate(conn, seg->ack)) {
-			log_msg(LVL_WARN, "Not acceptable, not duplicate. "
+			log_msg(LOG_DEFAULT, LVL_WARN, "Not acceptable, not duplicate. "
 			    "Send ACK and drop.");
 			/* Not acceptable, not duplicate. Send ACK and drop. */
@@ -746,5 +746,5 @@
 			return cp_done;
 		} else {
-			log_msg(LVL_DEBUG, "Ignoring duplicate ACK.");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Ignoring duplicate ACK.");
 		}
 	} else {
@@ -758,5 +758,5 @@
 		conn->snd_wl2 = seg->ack;
 
-		log_msg(LVL_DEBUG, "Updating send window, SND.WND=%" PRIu32
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Updating send window, SND.WND=%" PRIu32
 		    ", SND.WL1=%" PRIu32 ", SND.WL2=%" PRIu32,
 		    conn->snd_wnd, conn->snd_wl1, conn->snd_wl2);
@@ -785,5 +785,5 @@
 
 	if (conn->fin_is_acked) {
-		log_msg(LVL_DEBUG, "%s: FIN acked -> Fin-Wait-2", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN acked -> Fin-Wait-2", conn->name);
 		tcp_conn_state_set(conn, st_fin_wait_2);
 	}
@@ -850,5 +850,5 @@
 
 	if (conn->fin_is_acked) {
-		log_msg(LVL_DEBUG, "%s: FIN acked -> Closed", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN acked -> Closed", conn->name);
 		tcp_conn_remove(conn);
 		tcp_conn_state_set(conn, st_closed);
@@ -881,9 +881,9 @@
 static cproc_t tcp_conn_seg_proc_ack(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_seg_proc_ack(%p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_seg_proc_ack(%p, %p)",
 	    conn->name, conn, seg);
 
 	if ((seg->ctrl & CTL_ACK) == 0) {
-		log_msg(LVL_WARN, "Segment has no ACK. Dropping.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Segment has no ACK. Dropping.");
 		tcp_segment_delete(seg);
 		return cp_done;
@@ -940,5 +940,5 @@
 	size_t xfer_size;
 
-	log_msg(LVL_DEBUG, "%s: tcp_conn_seg_proc_text(%p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_seg_proc_text(%p, %p)",
 	    conn->name, conn, seg);
 
@@ -982,5 +982,5 @@
 	fibril_condvar_broadcast(&conn->rcv_buf_cv);
 
-	log_msg(LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Received %zu bytes of data.", xfer_size);
 
 	/* Advance RCV.NXT */
@@ -998,5 +998,5 @@
 		tcp_conn_trim_seg_to_wnd(conn, seg);
 	} else {
-		log_msg(LVL_DEBUG, "%s: Nothing left in segment, dropping "
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: Nothing left in segment, dropping "
 		    "(xfer_size=%zu, SEG.LEN=%" PRIu32 ", seg->ctrl=%u)",
 		    conn->name, xfer_size, seg->len, (unsigned int) seg->ctrl);
@@ -1018,12 +1018,12 @@
 static cproc_t tcp_conn_seg_proc_fin(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_seg_proc_fin(%p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_seg_proc_fin(%p, %p)",
 	    conn->name, conn, seg);
-	log_msg(LVL_DEBUG, " seg->len=%zu, seg->ctl=%u", (size_t) seg->len,
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " seg->len=%zu, seg->ctl=%u", (size_t) seg->len,
 	    (unsigned) seg->ctrl);
 
 	/* Only process FIN if no text is left in segment. */
 	if (tcp_segment_text_size(seg) == 0 && (seg->ctrl & CTL_FIN) != 0) {
-		log_msg(LVL_DEBUG, " - FIN found in segment.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, " - FIN found in segment.");
 
 		/* Send ACK */
@@ -1042,15 +1042,15 @@
 		case st_syn_received:
 		case st_established:
-			log_msg(LVL_DEBUG, "%s: FIN received -> Close-Wait",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN received -> Close-Wait",
 			    conn->name);
 			tcp_conn_state_set(conn, st_close_wait);
 			break;
 		case st_fin_wait_1:
-			log_msg(LVL_DEBUG, "%s: FIN received -> Closing",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN received -> Closing",
 			    conn->name);
 			tcp_conn_state_set(conn, st_closing);
 			break;
 		case st_fin_wait_2:
-			log_msg(LVL_DEBUG, "%s: FIN received -> Time-Wait",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: FIN received -> Time-Wait",
 			    conn->name);
 			tcp_conn_state_set(conn, st_time_wait);
@@ -1091,5 +1091,5 @@
 static void tcp_conn_seg_process(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_conn_seg_process(%p, %p)", conn, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_seg_process(%p, %p)", conn, seg);
 	tcp_segment_dump(seg);
 
@@ -1097,5 +1097,5 @@
 	/* XXX Permit valid ACKs, URGs and RSTs */
 /*	if (!seq_no_segment_acceptable(conn, seg)) {
-		log_msg(LVL_WARN, "Segment not acceptable, dropping.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Segment not acceptable, dropping.");
 		if ((seg->ctrl & CTL_RST) == 0) {
 			tcp_tqueue_ctrl_seg(conn, CTL_ACK);
@@ -1131,5 +1131,5 @@
 	 */
 	if (seg->len > 0) {
-		log_msg(LVL_DEBUG, "Re-insert segment %p. seg->len=%zu",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Re-insert segment %p. seg->len=%zu",
 		    seg, (size_t) seg->len);
 		tcp_iqueue_insert_seg(&conn->incoming, seg);
@@ -1146,5 +1146,5 @@
 void tcp_conn_segment_arrived(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_segment_arrived(%p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_segment_arrived(%p)",
 	    conn->name, seg);
 
@@ -1165,5 +1165,5 @@
 		tcp_conn_sa_queue(conn, seg); break;
 	case st_closed:
-		log_msg(LVL_DEBUG, "state=%d", (int) conn->cstate);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "state=%d", (int) conn->cstate);
 		assert(false);
 	}
@@ -1178,10 +1178,10 @@
 	tcp_conn_t *conn = (tcp_conn_t *) arg;
 
-	log_msg(LVL_DEBUG, "tw_timeout_func(%p)", conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tw_timeout_func(%p)", conn);
 
 	fibril_mutex_lock(&conn->lock);
 
 	if (conn->cstate == st_closed) {
-		log_msg(LVL_DEBUG, "Connection already closed.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Connection already closed.");
 		fibril_mutex_unlock(&conn->lock);
 		tcp_conn_delref(conn);
@@ -1189,5 +1189,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "%s: TW Timeout -> Closed", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: TW Timeout -> Closed", conn->name);
 	tcp_conn_remove(conn);
 	tcp_conn_state_set(conn, st_closed);
@@ -1240,5 +1240,5 @@
 void tcp_unexpected_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_unexpected_segment(%p, %p)", sp, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_unexpected_segment(%p, %p)", sp, seg);
 
 	if ((seg->ctrl & CTL_RST) == 0)
@@ -1268,5 +1268,5 @@
 	tcp_segment_t *rseg;
 
-	log_msg(LVL_DEBUG, "tcp_reply_rst(%p, %p)", sp, seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_reply_rst(%p, %p)", sp, seg);
 
 	rseg = tcp_segment_make_rst(seg);
Index: uspace/srv/net/tcp/iqueue.c
===================================================================
--- uspace/srv/net/tcp/iqueue.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/iqueue.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -67,9 +67,9 @@
 	tcp_iqueue_entry_t *qe;
 	link_t *link;
-	log_msg(LVL_DEBUG, "tcp_iqueue_insert_seg()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_iqueue_insert_seg()");
 
 	iqe = calloc(1, sizeof(tcp_iqueue_entry_t));
 	if (iqe == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating IQE.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating IQE.");
 		return;
 	}
@@ -108,9 +108,9 @@
 	link_t *link;
 
-	log_msg(LVL_DEBUG, "tcp_get_ready_seg()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_get_ready_seg()");
 
 	link = list_first(&iqueue->list);
 	if (link == NULL) {
-		log_msg(LVL_DEBUG, "iqueue is empty");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "iqueue is empty");
 		return ENOENT;
 	}
@@ -119,5 +119,5 @@
 
 	while (!seq_no_segment_acceptable(iqueue->conn, iqe->seg)) {
-		log_msg(LVL_DEBUG, "Skipping unacceptable segment (RCV.NXT=%"
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Skipping unacceptable segment (RCV.NXT=%"
 		    PRIu32 ", RCV.NXT+RCV.WND=%" PRIu32 ", SEG.SEQ=%" PRIu32
 		    ", SEG.LEN=%" PRIu32 ")", iqueue->conn->rcv_nxt,
@@ -130,5 +130,5 @@
          	link = list_first(&iqueue->list);
 		if (link == NULL) {
-			log_msg(LVL_DEBUG, "iqueue is empty");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "iqueue is empty");
 			return ENOENT;
 		}
@@ -139,5 +139,5 @@
 	/* Do not return segments that are not ready for processing */
 	if (!seq_no_segment_ready(iqueue->conn, iqe->seg)) {
-		log_msg(LVL_DEBUG, "Next segment not ready: SEG.SEQ=%u, "
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Next segment not ready: SEG.SEQ=%u, "
 		    "RCV.NXT=%u, SEG.LEN=%u", iqe->seg->seq,
 		    iqueue->conn->rcv_nxt, iqe->seg->len);
@@ -145,5 +145,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "Returning ready segment %p", iqe->seg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Returning ready segment %p", iqe->seg);
 	list_remove(&iqe->link);
 	*seg = iqe->seg;
Index: uspace/srv/net/tcp/ncsim.c
===================================================================
--- uspace/srv/net/tcp/ncsim.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/ncsim.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -74,5 +74,5 @@
 	link_t *link;
 
-	log_msg(LVL_DEBUG, "tcp_ncsim_bounce_seg()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ncsim_bounce_seg()");
 	tcp_rqueue_bounce_seg(sp, seg);
 	return;
@@ -80,5 +80,5 @@
 	if (0 /*random() % 4 == 3*/) {
 		/* Drop segment */
-		log_msg(LVL_ERROR, "NCSim dropping segment");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "NCSim dropping segment");
 		tcp_segment_delete(seg);
 		return;
@@ -87,5 +87,5 @@
 	sqe = calloc(1, sizeof(tcp_squeue_entry_t));
 	if (sqe == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating SQE.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating SQE.");
 		return;
 	}
@@ -126,5 +126,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_ncsim_fibril()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ncsim_fibril()");
 
 
@@ -139,5 +139,5 @@
 			sqe = list_get_instance(link, tcp_squeue_entry_t, link);
 
-			log_msg(LVL_DEBUG, "NCSim - Sleep");
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "NCSim - Sleep");
 			rc = fibril_condvar_wait_timeout(&sim_queue_cv,
 			    &sim_queue_lock, sqe->delay);
@@ -147,5 +147,5 @@
 		fibril_mutex_unlock(&sim_queue_lock);
 
-		log_msg(LVL_DEBUG, "NCSim - End Sleep");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "NCSim - End Sleep");
 		tcp_rqueue_bounce_seg(&sqe->sp, sqe->seg);
 		free(sqe);
@@ -161,9 +161,9 @@
 	fid_t fid;
 
-	log_msg(LVL_DEBUG, "tcp_ncsim_fibril_start()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_ncsim_fibril_start()");
 
 	fid = fibril_create(tcp_ncsim_fibril, NULL);
 	if (fid == 0) {
-		log_msg(LVL_ERROR, "Failed creating ncsim fibril.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed creating ncsim fibril.");
 		return;
 	}
Index: uspace/srv/net/tcp/rqueue.c
===================================================================
--- uspace/srv/net/tcp/rqueue.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/rqueue.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -74,5 +74,5 @@
 	tcp_sockpair_t rident;
 
-	log_msg(LVL_DEBUG, "tcp_rqueue_bounce_seg()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_bounce_seg()");
 
 #ifdef BOUNCE_TRANSCODE
@@ -81,10 +81,10 @@
 
 	if (tcp_pdu_encode(sp, seg, &pdu) != EOK) {
-		log_msg(LVL_WARN, "Not enough memory. Segment dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
 		return;
 	}
 
 	if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
-		log_msg(LVL_WARN, "Not enough memory. Segment dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
 		return;
 	}
@@ -112,5 +112,5 @@
 {
 	tcp_rqueue_entry_t *rqe;
-	log_msg(LVL_DEBUG, "tcp_rqueue_insert_seg()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_insert_seg()");
 
 	tcp_segment_dump(seg);
@@ -118,5 +118,5 @@
 	rqe = calloc(1, sizeof(tcp_rqueue_entry_t));
 	if (rqe == NULL) {
-		log_msg(LVL_ERROR, "Failed allocating RQE.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed allocating RQE.");
 		return;
 	}
@@ -134,5 +134,5 @@
 	tcp_rqueue_entry_t *rqe;
 
-	log_msg(LVL_DEBUG, "tcp_rqueue_fibril()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_fibril()");
 
 	while (true) {
@@ -152,9 +152,9 @@
 	fid_t fid;
 
-	log_msg(LVL_DEBUG, "tcp_rqueue_fibril_start()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_rqueue_fibril_start()");
 
 	fid = fibril_create(tcp_rqueue_fibril, NULL);
 	if (fid == 0) {
-		log_msg(LVL_ERROR, "Failed creating rqueue fibril.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed creating rqueue fibril.");
 		return;
 	}
Index: uspace/srv/net/tcp/segment.c
===================================================================
--- uspace/srv/net/tcp/segment.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/segment.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -248,11 +248,11 @@
 void tcp_segment_dump(tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG2, "Segment dump:");
-	log_msg(LVL_DEBUG2, " - ctrl = %u", (unsigned)seg->ctrl);
-	log_msg(LVL_DEBUG2, " - seq = %" PRIu32, seg->seq);
-	log_msg(LVL_DEBUG2, " - ack = %" PRIu32, seg->ack);
-	log_msg(LVL_DEBUG2, " - len = %" PRIu32, seg->len);
-	log_msg(LVL_DEBUG2, " - wnd = %" PRIu32, seg->wnd);
-	log_msg(LVL_DEBUG2, " - up = %" PRIu32, seg->up);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, "Segment dump:");
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - ctrl = %u", (unsigned)seg->ctrl);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - seq = %" PRIu32, seg->seq);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - ack = %" PRIu32, seg->ack);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - len = %" PRIu32, seg->len);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - wnd = %" PRIu32, seg->wnd);
+	log_msg(LOG_DEFAULT, LVL_DEBUG2, " - up = %" PRIu32, seg->up);
 }
 
Index: uspace/srv/net/tcp/sock.c
===================================================================
--- uspace/srv/net/tcp/sock.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/sock.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -91,5 +91,5 @@
 static void tcp_sock_notify_data(socket_core_t *sock_core)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_data(%d)", sock_core->socket_id);
 	async_exch_t *exch = async_exchange_begin(sock_core->sess);
 	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
@@ -100,5 +100,5 @@
 static void tcp_sock_notify_aconn(socket_core_t *lsock_core)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_notify_aconn(%d)", lsock_core->socket_id);
 	async_exch_t *exch = async_exchange_begin(lsock_core->sess);
 	async_msg_5(exch, NET_SOCKET_ACCEPTED, (sysarg_t)lsock_core->socket_id,
@@ -111,5 +111,5 @@
 	tcp_sockdata_t *sock;
 
-	log_msg(LVL_DEBUG, "tcp_sock_create()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_create()");
 	*rsock = NULL;
 
@@ -133,5 +133,5 @@
 static void tcp_sock_uncreate(tcp_sockdata_t *sock)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_uncreate()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_uncreate()");
 	free(sock);
 }
@@ -142,5 +142,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_finish_setup()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_finish_setup()");
 
 	sock->recv_fibril = fibril_create(tcp_sock_recv_fibril, sock);
@@ -171,5 +171,5 @@
 	ipc_call_t answer;
 
-	log_msg(LVL_DEBUG, "tcp_sock_socket()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_socket()");
 
 	rc = tcp_sock_create(client, &sock);
@@ -208,6 +208,6 @@
 	tcp_sockdata_t *socket;
 
-	log_msg(LVL_DEBUG, "tcp_sock_bind()");
-	log_msg(LVL_DEBUG, " - async_data_write_accept");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_bind()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
 	rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
 	if (rc != EOK) {
@@ -216,5 +216,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - call socket_bind");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
 	rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
 	    addr, addr_len, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
@@ -225,5 +225,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - call socket_cores_find");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
 	sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
 	if (sock_core != NULL) {
@@ -233,5 +233,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - success");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
 	async_answer_0(callid, EOK);
 }
@@ -250,5 +250,5 @@
 	int i;
 
-	log_msg(LVL_DEBUG, "tcp_sock_listen()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_listen()");
 
 	socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -284,5 +284,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - open connections");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - open connections");
 
 	lsocket.addr.ipv4 = TCP_IPV4_ANY;
@@ -337,5 +337,5 @@
 	tcp_sock_t fsocket;
 
-	log_msg(LVL_DEBUG, "tcp_sock_connect()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect()");
 
 	rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &addr_len);
@@ -377,5 +377,5 @@
 			fibril_mutex_unlock(&socket->lock);
 			async_answer_0(callid, rc);
-			log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connect: Failed to "
 			    "determine local address.");
 			return;
@@ -383,5 +383,5 @@
 
 		socket->laddr.ipv4 = loc_addr.ipv4;
-		log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
 	}
 
@@ -431,5 +431,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_accept()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept()");
 
 	socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -445,5 +445,5 @@
 	fibril_mutex_lock(&socket->lock);
 
-	log_msg(LVL_DEBUG, " - verify socket->conn");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - verify socket->conn");
 	if (socket->conn != NULL) {
 		fibril_mutex_unlock(&socket->lock);
@@ -498,5 +498,5 @@
 
 	asocket->conn = conn;
-	log_msg(LVL_DEBUG, "tcp_sock_accept():create asocket\n");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept():create asocket\n");
 
 	rc = tcp_sock_finish_setup(asocket, &asock_id);
@@ -510,5 +510,5 @@
 	fibril_add_ready(asocket->recv_fibril);
 
-	log_msg(LVL_DEBUG, "tcp_sock_accept(): find acore\n");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): find acore\n");
 
 	SOCKET_SET_DATA_FRAGMENT_SIZE(answer, TCP_SOCK_FRAGMENT_SIZE);
@@ -521,5 +521,5 @@
 	
 	/* Push one fragment notification to client's queue */
-	log_msg(LVL_DEBUG, "tcp_sock_accept(): notify data\n");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_accept(): notify data\n");
 	fibril_mutex_unlock(&socket->lock);
 }
@@ -539,5 +539,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_send()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_send()");
 	socket_id = SOCKET_GET_SOCKET_ID(call);
 	fragments = SOCKET_GET_DATA_FRAGMENTS(call);
@@ -611,5 +611,5 @@
 static void tcp_sock_sendto(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_sendto()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_sendto()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -629,5 +629,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "%p: tcp_sock_recv[from]()", client);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: tcp_sock_recv[from]()", client);
 
 	socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -651,13 +651,13 @@
 	(void)flags;
 
-	log_msg(LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom(): lock recv_buffer_lock");
 	fibril_mutex_lock(&socket->recv_buffer_lock);
 	while (socket->recv_buffer_used == 0 && socket->recv_error == TCP_EOK) {
-		log_msg(LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "wait for recv_buffer_cv + recv_buffer_used != 0");
 		fibril_condvar_wait(&socket->recv_buffer_cv,
 		    &socket->recv_buffer_lock);
 	}
 
-	log_msg(LVL_DEBUG, "Got data in sock recv_buffer");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
 
 	data_len = socket->recv_buffer_used;
@@ -679,5 +679,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "**** recv result -> %d", rc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv result -> %d", rc);
 	if (rc != EOK) {
 		fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -694,5 +694,5 @@
 		addr.sin_port = host2uint16_t_be(rsock->port);
 
-		log_msg(LVL_DEBUG, "addr read receive");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
 		if (!async_data_read_receive(&rcallid, &addr_length)) {
 			fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -705,5 +705,5 @@
 			addr_length = sizeof(addr);
 
-		log_msg(LVL_DEBUG, "addr read finalize");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
 		rc = async_data_read_finalize(rcallid, &addr, addr_length);
 		if (rc != EOK) {
@@ -715,5 +715,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "data read receive");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
 	if (!async_data_read_receive(&rcallid, &length)) {
 		fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -726,9 +726,9 @@
 		length = data_len;
 
-	log_msg(LVL_DEBUG, "data read finalize");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
 	rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
 
 	socket->recv_buffer_used -= length;
-	log_msg(LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recvfrom: %zu left in buffer",
 	    socket->recv_buffer_used);
 	if (socket->recv_buffer_used > 0) {
@@ -758,5 +758,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_close()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()");
 	socket_id = SOCKET_GET_SOCKET_ID(call);
 
@@ -798,5 +798,5 @@
 static void tcp_sock_getsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_getsockopt()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_getsockopt()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -804,5 +804,5 @@
 static void tcp_sock_setsockopt(tcp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "tcp_sock_setsockopt()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_setsockopt()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -815,5 +815,5 @@
 	tcp_sockdata_t *socket = lconn->socket;
 
-	log_msg(LVL_DEBUG, "tcp_sock_cstate_cb()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb()");
 	fibril_mutex_lock(&socket->lock);
 	assert(conn == lconn->conn);
@@ -828,5 +828,5 @@
 	list_append(&lconn->ready_list, &socket->ready);
 
-	log_msg(LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_cstate_cb(): notify accept");
 
 	/* Push one accept notification to client's queue */
@@ -842,10 +842,10 @@
 	tcp_error_t trc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_recv_fibril()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_recv_fibril()");
 
 	fibril_mutex_lock(&sock->recv_buffer_lock);
 
 	while (true) {
-		log_msg(LVL_DEBUG, "call tcp_uc_receive()");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "call tcp_uc_receive()");
 		while (sock->recv_buffer_used != 0 && sock->sock_core != NULL)
 			fibril_condvar_wait(&sock->recv_buffer_cv,
@@ -863,5 +863,5 @@
 		}
 
-		log_msg(LVL_DEBUG, "got data - broadcast recv_buffer_cv");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "got data - broadcast recv_buffer_cv");
 
 		sock->recv_buffer_used = data_len;
@@ -895,5 +895,5 @@
 			break;
 
-		log_msg(LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: METHOD=%d\n",
 		    (int)IPC_GET_IMETHOD(call));
 
@@ -940,5 +940,5 @@
 
 	/* Clean up */
-	log_msg(LVL_DEBUG, "tcp_sock_connection: Clean up");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_connection: Clean up");
 	async_hangup(client.sess);
 	socket_cores_release(NULL, &client.sockets, &gsock, tcp_free_sock_data);
Index: uspace/srv/net/tcp/tcp.c
===================================================================
--- uspace/srv/net/tcp/tcp.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/tcp.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -69,5 +69,5 @@
 	size_t pdu_raw_size;
 
-	log_msg(LVL_DEBUG, "tcp_inet_ev_recv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv()");
 
 	pdu_raw = dgram->data;
@@ -76,5 +76,5 @@
 	/* Split into header and payload. */
 
-	log_msg(LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
 
 	tcp_pdu_t *pdu;
@@ -84,5 +84,5 @@
 
 	if (pdu_raw_size < sizeof(tcp_header_t)) {
-		log_msg(LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
+		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
 		    pdu_raw_size, sizeof(tcp_header_t));
 		return EINVAL;
@@ -96,5 +96,5 @@
 
 	if (pdu_raw_size < hdr_size) {
-		log_msg(LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
+		log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
 		    pdu_raw_size, hdr_size);
 		return EINVAL;
@@ -102,14 +102,14 @@
 
 	if (hdr_size < sizeof(tcp_header_t)) {
-		log_msg(LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
+		log_msg(LOG_DEFAULT, LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
 		    hdr_size, sizeof(tcp_header_t));		return EINVAL;
 	}
 
-	log_msg(LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
 	    pdu_raw_size, hdr_size);
 	pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size,
 	    pdu_raw_size - hdr_size);
 	if (pdu == NULL) {
-		log_msg(LVL_WARN, "Failed creating PDU. Dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Failed creating PDU. Dropped.");
 		return ENOMEM;
 	}
@@ -117,5 +117,5 @@
 	pdu->src_addr.ipv4 = dgram->src.ipv4;
 	pdu->dest_addr.ipv4 = dgram->dest.ipv4;
-	log_msg(LVL_DEBUG, "src: 0x%08x, dest: 0x%08x",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "src: 0x%08x, dest: 0x%08x",
 	    pdu->src_addr.ipv4, pdu->dest_addr.ipv4);
 
@@ -137,5 +137,5 @@
 	pdu_raw = malloc(pdu_raw_size);
 	if (pdu_raw == NULL) {
-		log_msg(LVL_ERROR, "Failed to transmit PDU. Out of memory.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU. Out of memory.");
 		return;
 	}
@@ -153,5 +153,5 @@
 	rc = inet_send(&dgram, INET_TTL_MAX, 0);
 	if (rc != EOK)
-		log_msg(LVL_ERROR, "Failed to transmit PDU.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
 }
 
@@ -162,8 +162,8 @@
 	tcp_sockpair_t rident;
 
-	log_msg(LVL_DEBUG, "tcp_received_pdu()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
 
 	if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
-		log_msg(LVL_WARN, "Not enough memory. PDU dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
 		return;
 	}
@@ -177,5 +177,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_init()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_init()");
 
 	tcp_rqueue_init();
@@ -189,5 +189,5 @@
 	rc = inet_init(IP_PROTO_TCP, &tcp_inet_ev_ops);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed connecting to internet service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
 		return ENOENT;
 	}
@@ -195,5 +195,5 @@
 	rc = tcp_sock_init();
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed initializing socket service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing socket service.");
 		return ENOENT;
 	}
@@ -208,5 +208,5 @@
 	printf(NAME ": TCP (Transmission Control Protocol) network module\n");
 
-	rc = log_init(NAME, LVL_WARN);
+	rc = log_init(NAME);
 	if (rc != EOK) {
 		printf(NAME ": Failed to initialize log.\n");
Index: uspace/srv/net/tcp/tqueue.c
===================================================================
--- uspace/srv/net/tcp/tqueue.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/tqueue.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -88,5 +88,5 @@
 	tcp_segment_t *seg;
 
-	log_msg(LVL_DEBUG, "tcp_tqueue_ctrl_seg(%p, %u)", conn, ctrl);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_tqueue_ctrl_seg(%p, %u)", conn, ctrl);
 
 	seg = tcp_segment_make_ctrl(ctrl);
@@ -99,5 +99,5 @@
 	tcp_tqueue_entry_t *tqe;
 
-	log_msg(LVL_DEBUG, "%s: tcp_tqueue_seg(%p, %p)", conn->name, conn,
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_tqueue_seg(%p, %p)", conn->name, conn,
 	    seg);
 
@@ -109,5 +109,5 @@
 		rt_seg = tcp_segment_dup(seg);
 		if (rt_seg == NULL) {
-			log_msg(LVL_ERROR, "Memory allocation failed.");
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failed.");
 			/* XXX Handle properly */
 			return;
@@ -116,5 +116,5 @@
 		tqe = calloc(1, sizeof(tcp_tqueue_entry_t));
 		if (tqe == NULL) {
-			log_msg(LVL_ERROR, "Memory allocation failed.");
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failed.");
 			/* XXX Handle properly */
 			return;
@@ -165,5 +165,5 @@
 	tcp_segment_t *seg;
 
-	log_msg(LVL_DEBUG, "%s: tcp_tqueue_new_data()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_tqueue_new_data()", conn->name);
 
 	/* Number of free sequence numbers in send window */
@@ -172,5 +172,5 @@
 
 	xfer_seqlen = min(snd_buf_seqlen, avail_wnd);
-	log_msg(LVL_DEBUG, "%s: snd_buf_seqlen = %zu, SND.WND = %" PRIu32 ", "
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: snd_buf_seqlen = %zu, SND.WND = %" PRIu32 ", "
 	    "xfer_seqlen = %zu", conn->name, snd_buf_seqlen, conn->snd_wnd,
 	    xfer_seqlen);
@@ -185,5 +185,5 @@
 
 	if (send_fin) {
-		log_msg(LVL_DEBUG, "%s: Sending out FIN.", conn->name);
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: Sending out FIN.", conn->name);
 		/* We are sending out FIN */
 		ctrl = CTL_FIN;
@@ -194,5 +194,5 @@
 	seg = tcp_segment_make_data(ctrl, conn->snd_buf, data_size);
 	if (seg == NULL) {
-		log_msg(LVL_ERROR, "Memory allocation failure.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failure.");
 		return;
 	}
@@ -223,5 +223,5 @@
 	link_t *cur, *next;
 
-	log_msg(LVL_DEBUG, "%s: tcp_tqueue_ack_received(%p)", conn->name,
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_tqueue_ack_received(%p)", conn->name,
 	    conn);
 
@@ -239,6 +239,6 @@
 
 			if ((tqe->seg->ctrl & CTL_FIN) != 0) {
-				log_msg(LVL_DEBUG, "Fin has been acked");
-				log_msg(LVL_DEBUG, "SND.UNA=%" PRIu32
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "Fin has been acked");
+				log_msg(LOG_DEFAULT, LVL_DEBUG, "SND.UNA=%" PRIu32
 				    " SEG.SEQ=%" PRIu32 " SEG.LEN=%" PRIu32,
 				    conn->snd_una, tqe->seg->seq, tqe->seg->len);
@@ -267,5 +267,5 @@
 void tcp_conn_transmit_segment(tcp_conn_t *conn, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_conn_transmit_segment(%p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_transmit_segment(%p, %p)",
 	    conn->name, conn, seg);
 
@@ -282,9 +282,9 @@
 void tcp_transmit_segment(tcp_sockpair_t *sp, tcp_segment_t *seg)
 {
-	log_msg(LVL_DEBUG, "tcp_transmit_segment(f:(%x,%u),l:(%x,%u), %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_transmit_segment(f:(%x,%u),l:(%x,%u), %p)",
 	    sp->foreign.addr.ipv4, sp->foreign.port,
 	    sp->local.addr.ipv4, sp->local.port, seg);
 
-	log_msg(LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "SEG.SEQ=%" PRIu32 ", SEG.WND=%" PRIu32,
 	    seg->seq, seg->wnd);
 
@@ -300,5 +300,5 @@
 
 	if (tcp_pdu_encode(sp, seg, &pdu) != EOK) {
-		log_msg(LVL_WARN, "Not enough memory. Segment dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. Segment dropped.");
 		return;
 	}
@@ -315,10 +315,10 @@
 	link_t *link;
 
-	log_msg(LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: retransmit_timeout_func(%p)", conn->name, conn);
 
 	fibril_mutex_lock(&conn->lock);
 
 	if (conn->cstate == st_closed) {
-		log_msg(LVL_DEBUG, "Connection already closed.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Connection already closed.");
 		fibril_mutex_unlock(&conn->lock);
 		tcp_conn_delref(conn);
@@ -328,5 +328,5 @@
 	link = list_first(&conn->retransmit.list);
 	if (link == NULL) {
-		log_msg(LVL_DEBUG, "Nothing to retransmit");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Nothing to retransmit");
 		fibril_mutex_unlock(&conn->lock);
 		tcp_conn_delref(conn);
@@ -338,5 +338,5 @@
 	rt_seg = tcp_segment_dup(tqe->seg);
 	if (rt_seg == NULL) {
-		log_msg(LVL_ERROR, "Memory allocation failed.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failed.");
 		fibril_mutex_unlock(&conn->lock);
 		tcp_conn_delref(conn);
@@ -345,5 +345,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "### %s: retransmitting segment", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: retransmitting segment", conn->name);
 	tcp_conn_transmit_segment(tqe->conn, rt_seg);
 
@@ -358,5 +358,5 @@
 static void tcp_tqueue_timer_set(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: tcp_tqueue_timer_set()", conn->name);
 
 	/* Clear first to make sure we update refcnt correctly */
@@ -371,5 +371,5 @@
 static void tcp_tqueue_timer_clear(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "### %s: tcp_tqueue_timer_clear()", conn->name);
 
 	if (fibril_timer_clear(conn->retransmit.timer) == fts_active)
Index: uspace/srv/net/tcp/ucall.c
===================================================================
--- uspace/srv/net/tcp/ucall.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/tcp/ucall.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -70,5 +70,5 @@
 	tcp_conn_t *nconn;
 
-	log_msg(LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %s, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open(%p, %p, %s, %s, %p)",
 	    lsock, fsock, acpass == ap_active ? "active" : "passive",
 	    oflags == tcp_open_nonblock ? "nonblock" : "none", conn);
@@ -88,5 +88,5 @@
 
 	/* Wait for connection to be established or reset */
-	log_msg(LVL_DEBUG, "tcp_uc_open: Wait for connection.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Wait for connection.");
 	fibril_mutex_lock(&nconn->lock);
 	while (nconn->cstate == st_listen ||
@@ -97,5 +97,5 @@
 
 	if (nconn->cstate != st_established) {
-		log_msg(LVL_DEBUG, "tcp_uc_open: Connection was reset.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Connection was reset.");
 		assert(nconn->cstate == st_closed);
 		fibril_mutex_unlock(&nconn->lock);
@@ -104,8 +104,8 @@
 
 	fibril_mutex_unlock(&nconn->lock);
-	log_msg(LVL_DEBUG, "tcp_uc_open: Connection was established.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open: Connection was established.");
 
 	*conn = nconn;
-	log_msg(LVL_DEBUG, "tcp_uc_open -> %p", nconn);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_open -> %p", nconn);
 	return TCP_EOK;
 }
@@ -118,5 +118,5 @@
 	size_t xfer_size;
 
-	log_msg(LVL_DEBUG, "%s: tcp_uc_send()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_send()", conn->name);
 
 	fibril_mutex_lock(&conn->lock);
@@ -141,5 +141,5 @@
 		buf_free = conn->snd_buf_size - conn->snd_buf_used;
 		while (buf_free == 0 && !conn->reset) {
-			log_msg(LVL_DEBUG, "%s: buf_free == 0, waiting.",
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: buf_free == 0, waiting.",
 			    conn->name);
 			fibril_condvar_wait(&conn->snd_buf_cv, &conn->lock);
@@ -175,5 +175,5 @@
 	size_t xfer_size;
 
-	log_msg(LVL_DEBUG, "%s: tcp_uc_receive()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_receive()", conn->name);
 
 	fibril_mutex_lock(&conn->lock);
@@ -186,5 +186,5 @@
 	/* Wait for data to become available */
 	while (conn->rcv_buf_used == 0 && !conn->rcv_buf_fin && !conn->reset) {
-		log_msg(LVL_DEBUG, "tcp_uc_receive() - wait for data");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_receive() - wait for data");
 		fibril_condvar_wait(&conn->rcv_buf_cv, &conn->lock);
 	}
@@ -223,5 +223,5 @@
 	tcp_tqueue_ctrl_seg(conn, CTL_ACK);
 
-	log_msg(LVL_DEBUG, "%s: tcp_uc_receive() - returning %zu bytes",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_receive() - returning %zu bytes",
 	    conn->name, xfer_size);
 
@@ -234,5 +234,5 @@
 tcp_error_t tcp_uc_close(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "%s: tcp_uc_close()", conn->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_close()", conn->name);
 
 	fibril_mutex_lock(&conn->lock);
@@ -258,5 +258,5 @@
 void tcp_uc_abort(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "tcp_uc_abort()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_abort()");
 }
 
@@ -264,5 +264,5 @@
 void tcp_uc_status(tcp_conn_t *conn, tcp_conn_status_t *cstatus)
 {
-	log_msg(LVL_DEBUG, "tcp_uc_status()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_status()");
 	cstatus->cstate = conn->cstate;
 }
@@ -276,5 +276,5 @@
 void tcp_uc_delete(tcp_conn_t *conn)
 {
-	log_msg(LVL_DEBUG, "tcp_uc_delete()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_delete()");
 	tcp_conn_delete(conn);
 }
@@ -282,5 +282,5 @@
 void tcp_uc_set_cstate_cb(tcp_conn_t *conn, tcp_cstate_cb_t cb, void *arg)
 {
-	log_msg(LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_set_ctate_cb(%p, %p, %p)",
 	    conn, cb, arg);
 
@@ -298,5 +298,5 @@
 	tcp_conn_t *conn;
 
-	log_msg(LVL_DEBUG, "tcp_as_segment_arrived(f:(%x,%u), l:(%x,%u))",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_as_segment_arrived(f:(%x,%u), l:(%x,%u))",
 	    sp->foreign.addr.ipv4, sp->foreign.port,
 	    sp->local.addr.ipv4, sp->local.port);
@@ -304,5 +304,5 @@
 	conn = tcp_conn_find_ref(sp);
 	if (conn == NULL) {
-		log_msg(LVL_WARN, "No connection found.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "No connection found.");
 		tcp_unexpected_segment(sp, seg);
 		return;
@@ -312,5 +312,5 @@
 
 	if (conn->cstate == st_closed) {
-		log_msg(LVL_WARN, "Connection is closed.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Connection is closed.");
 		tcp_unexpected_segment(sp, seg);
 		fibril_mutex_unlock(&conn->lock);
@@ -339,5 +339,5 @@
 void tcp_to_user(void)
 {
-	log_msg(LVL_DEBUG, "tcp_to_user()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_to_user()");
 }
 
Index: uspace/srv/net/udp/assoc.c
===================================================================
--- uspace/srv/net/udp/assoc.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/udp/assoc.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -104,5 +104,5 @@
 static void udp_assoc_free(udp_assoc_t *assoc)
 {
-	log_msg(LVL_DEBUG, "%s: udp_assoc_free(%p)", assoc->name, assoc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_assoc_free(%p)", assoc->name, assoc);
 
 	while (!list_empty(&assoc->rcv_queue)) {
@@ -127,5 +127,5 @@
 void udp_assoc_addref(udp_assoc_t *assoc)
 {
-	log_msg(LVL_DEBUG, "%s: upd_assoc_addref(%p)", assoc->name, assoc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: upd_assoc_addref(%p)", assoc->name, assoc);
 	atomic_inc(&assoc->refcnt);
 }
@@ -139,5 +139,5 @@
 void udp_assoc_delref(udp_assoc_t *assoc)
 {
-	log_msg(LVL_DEBUG, "%s: udp_assoc_delref(%p)", assoc->name, assoc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_assoc_delref(%p)", assoc->name, assoc);
 
 	if (atomic_predec(&assoc->refcnt) == 0)
@@ -154,5 +154,5 @@
 void udp_assoc_delete(udp_assoc_t *assoc)
 {
-	log_msg(LVL_DEBUG, "%s: udp_assoc_delete(%p)", assoc->name, assoc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_assoc_delete(%p)", assoc->name, assoc);
 
 	assert(assoc->deleted == false);
@@ -192,5 +192,5 @@
 void udp_assoc_set_foreign(udp_assoc_t *assoc, udp_sock_t *fsock)
 {
-	log_msg(LVL_DEBUG, "udp_assoc_set_foreign(%p, %p)", assoc, fsock);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_foreign(%p, %p)", assoc, fsock);
 	fibril_mutex_lock(&assoc->lock);
 	assoc->ident.foreign = *fsock;
@@ -205,5 +205,5 @@
 void udp_assoc_set_local(udp_assoc_t *assoc, udp_sock_t *lsock)
 {
-	log_msg(LVL_DEBUG, "udp_assoc_set_local(%p, %p)", assoc, lsock);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_set_local(%p, %p)", assoc, lsock);
 	fibril_mutex_lock(&assoc->lock);
 	assoc->ident.local = *lsock;
@@ -228,5 +228,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "udp_assoc_send(%p, %p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_send(%p, %p, %p)",
 	    assoc, fsock, msg);
 
@@ -261,13 +261,13 @@
 	udp_rcv_queue_entry_t *rqe;
 
-	log_msg(LVL_DEBUG, "udp_assoc_recv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_recv()");
 
 	fibril_mutex_lock(&assoc->lock);
 	while (list_empty(&assoc->rcv_queue)) {
-		log_msg(LVL_DEBUG, "udp_assoc_recv() - waiting");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_recv() - waiting");
 		fibril_condvar_wait(&assoc->rcv_queue_cv, &assoc->lock);
 	}
 
-	log_msg(LVL_DEBUG, "udp_assoc_recv() - got a message");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_recv() - got a message");
 	link = list_first(&assoc->rcv_queue);
 	rqe = list_get_instance(link, udp_rcv_queue_entry_t, link);
@@ -291,9 +291,9 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_received(%p, %p)", rsp, msg);
 
 	assoc = udp_assoc_find_ref(rsp);
 	if (assoc == NULL) {
-		log_msg(LVL_DEBUG, "No association found. Message dropped.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "No association found. Message dropped.");
 		/* XXX Generate ICMP error. */
 		/* XXX Might propagate error directly by error return. */
@@ -303,5 +303,5 @@
 	rc = udp_assoc_queue_msg(assoc, rsp, msg);
 	if (rc != EOK) {
-		log_msg(LVL_DEBUG, "Out of memory. Message dropped.");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Out of memory. Message dropped.");
 		/* XXX Generate ICMP error? */
 	}
@@ -313,5 +313,5 @@
 	udp_rcv_queue_entry_t *rqe;
 
-	log_msg(LVL_DEBUG, "udp_assoc_queue_msg(%p, %p, %p)",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_queue_msg(%p, %p, %p)",
 	    assoc, sp, msg);
 
@@ -336,5 +336,5 @@
 static bool udp_socket_match(udp_sock_t *sock, udp_sock_t *patt)
 {
-	log_msg(LVL_DEBUG, "udp_socket_match(sock=(%x,%u), pat=(%x,%u))",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_socket_match(sock=(%x,%u), pat=(%x,%u))",
 	    sock->addr.ipv4, sock->port, patt->addr.ipv4, patt->port);
 
@@ -347,5 +347,5 @@
 		return false;
 
-	log_msg(LVL_DEBUG, " -> match");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " -> match");
 
 	return true;
@@ -355,5 +355,5 @@
 static bool udp_sockpair_match(udp_sockpair_t *sp, udp_sockpair_t *pattern)
 {
-	log_msg(LVL_DEBUG, "udp_sockpair_match(%p, %p)", sp, pattern);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sockpair_match(%p, %p)", sp, pattern);
 
 	if (!udp_socket_match(&sp->local, &pattern->local))
@@ -363,5 +363,5 @@
 		return false;
 
-	log_msg(LVL_DEBUG, "Socket pair matched.");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Socket pair matched.");
 	return true;
 }
@@ -379,5 +379,5 @@
 static udp_assoc_t *udp_assoc_find_ref(udp_sockpair_t *sp)
 {
-	log_msg(LVL_DEBUG, "udp_assoc_find_ref(%p)", sp);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_find_ref(%p)", sp);
 
 	fibril_mutex_lock(&assoc_list_lock);
@@ -386,5 +386,5 @@
 		udp_assoc_t *assoc = list_get_instance(link, udp_assoc_t, link);
 		udp_sockpair_t *asp = &assoc->ident;
-		log_msg(LVL_DEBUG, "compare with assoc (f:(%x,%u), l:(%x,%u))",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "compare with assoc (f:(%x,%u), l:(%x,%u))",
 		    asp->foreign.addr.ipv4, asp->foreign.port,
 		    asp->local.addr.ipv4, asp->local.port);
@@ -395,5 +395,5 @@
 
 		if (udp_sockpair_match(sp, asp)) {
-			log_msg(LVL_DEBUG, "Returning assoc %p", assoc);
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "Returning assoc %p", assoc);
 			udp_assoc_addref(assoc);
 			fibril_mutex_unlock(&assoc_list_lock);
Index: uspace/srv/net/udp/sock.c
===================================================================
--- uspace/srv/net/udp/sock.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/udp/sock.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -88,5 +88,5 @@
 static void udp_sock_notify_data(socket_core_t *sock_core)
 {
-	log_msg(LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_notify_data(%d)", sock_core->socket_id);
 	async_exch_t *exch = async_exchange_begin(sock_core->sess);
 	async_msg_5(exch, NET_SOCKET_RECEIVED, (sysarg_t)sock_core->socket_id,
@@ -103,5 +103,5 @@
 	ipc_call_t answer;
 
-	log_msg(LVL_DEBUG, "udp_sock_socket()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_socket()");
 	sock = calloc(1, sizeof(udp_sockdata_t));
 	if (sock == NULL) {
@@ -167,6 +167,6 @@
 	udp_error_t urc;
 
-	log_msg(LVL_DEBUG, "udp_sock_bind()");
-	log_msg(LVL_DEBUG, " - async_data_write_accept");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_bind()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - async_data_write_accept");
 
 	addr = NULL;
@@ -178,5 +178,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - call socket_bind");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_bind");
 	rc = socket_bind(&client->sockets, &gsock, SOCKET_GET_SOCKET_ID(call),
 	    addr, addr_size, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
@@ -192,5 +192,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - call socket_cores_find");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - call socket_cores_find");
 	sock_core = socket_cores_find(&client->sockets, SOCKET_GET_SOCKET_ID(call));
 	if (sock_core == NULL) {
@@ -222,5 +222,5 @@
 	}
 
-	log_msg(LVL_DEBUG, " - success");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, " - success");
 	async_answer_0(callid, rc);
 out:
@@ -231,5 +231,5 @@
 static void udp_sock_listen(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "udp_sock_listen()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_listen()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -237,5 +237,5 @@
 static void udp_sock_connect(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "udp_sock_connect()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connect()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -243,5 +243,5 @@
 static void udp_sock_accept(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "udp_sock_accept()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_accept()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -264,5 +264,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "udp_sock_send()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_send()");
 
 	addr = NULL;
@@ -323,5 +323,5 @@
 			fibril_mutex_unlock(&socket->lock);
 			async_answer_0(callid, rc);
-			log_msg(LVL_DEBUG, "udp_sock_sendto: Failed to "
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_sendto: Failed to "
 			    "determine local address.");
 			return;
@@ -329,5 +329,5 @@
 
 		socket->assoc->ident.local.addr.ipv4 = loc_addr.ipv4;
-		log_msg(LVL_DEBUG, "Local IP address is %x",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "Local IP address is %x",
 		    socket->assoc->ident.local.addr.ipv4);
 	}
@@ -405,5 +405,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%p: udp_sock_recv[from]()", client);
 
 	socket_id = SOCKET_GET_SOCKET_ID(call);
@@ -427,13 +427,13 @@
 	(void)flags;
 
-	log_msg(LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): lock recv_buffer lock");
 	fibril_mutex_lock(&socket->recv_buffer_lock);
 	while (socket->recv_buffer_used == 0 && socket->recv_error == UDP_EOK) {
-		log_msg(LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recvfrom(): wait for cv");
 		fibril_condvar_wait(&socket->recv_buffer_cv,
 		    &socket->recv_buffer_lock);
 	}
 
-	log_msg(LVL_DEBUG, "Got data in sock recv_buffer");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "Got data in sock recv_buffer");
 
 	rsock = socket->recv_fsock;
@@ -441,5 +441,5 @@
 	urc = socket->recv_error;
 
-	log_msg(LVL_DEBUG, "**** recv data_len=%zu", data_len);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "**** recv data_len=%zu", data_len);
 
 	switch (urc) {
@@ -458,5 +458,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "**** udp_uc_receive -> %d", rc);
 	if (rc != EOK) {
 		fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -472,5 +472,5 @@
 		addr.sin_port = host2uint16_t_be(rsock.port);
 
-		log_msg(LVL_DEBUG, "addr read receive");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read receive");
 		if (!async_data_read_receive(&rcallid, &addr_length)) {
 			fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -483,5 +483,5 @@
 			addr_length = sizeof(addr);
 
-		log_msg(LVL_DEBUG, "addr read finalize");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "addr read finalize");
 		rc = async_data_read_finalize(rcallid, &addr, addr_length);
 		if (rc != EOK) {
@@ -493,5 +493,5 @@
 	}
 
-	log_msg(LVL_DEBUG, "data read receive");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read receive");
 	if (!async_data_read_receive(&rcallid, &length)) {
 		fibril_mutex_unlock(&socket->recv_buffer_lock);
@@ -504,5 +504,5 @@
 		length = data_len;
 
-	log_msg(LVL_DEBUG, "data read finalize");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "data read finalize");
 	rc = async_data_read_finalize(rcallid, socket->recv_buffer, length);
 
@@ -510,5 +510,5 @@
 		rc = EOVERFLOW;
 
-	log_msg(LVL_DEBUG, "read_data_length <- %zu", length);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "read_data_length <- %zu", length);
 	IPC_SET_ARG2(answer, 0);
 	SOCKET_SET_READ_DATA_LENGTH(answer, length);
@@ -531,5 +531,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "tcp_sock_close()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_sock_close()");
 	socket_id = SOCKET_GET_SOCKET_ID(call);
 
@@ -557,5 +557,5 @@
 static void udp_sock_getsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "udp_sock_getsockopt()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_getsockopt()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -563,5 +563,5 @@
 static void udp_sock_setsockopt(udp_client_t *client, ipc_callid_t callid, ipc_call_t call)
 {
-	log_msg(LVL_DEBUG, "udp_sock_setsockopt()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_setsockopt()");
 	async_answer_0(callid, ENOTSUP);
 }
@@ -574,8 +574,8 @@
 	size_t rcvd;
 
-	log_msg(LVL_DEBUG, "udp_sock_recv_fibril()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_recv_fibril()");
 
 	while (true) {
-		log_msg(LVL_DEBUG, "[] wait for rcv buffer empty()");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "[] wait for rcv buffer empty()");
 		fibril_mutex_lock(&sock->recv_buffer_lock);
 		while (sock->recv_buffer_used != 0) {
@@ -584,5 +584,5 @@
 		}
 
-		log_msg(LVL_DEBUG, "[] call udp_uc_receive()");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "[] call udp_uc_receive()");
 		urc = udp_uc_receive(sock->assoc, sock->recv_buffer,
 		    UDP_FRAGMENT_SIZE, &rcvd, &xflags, &sock->recv_fsock);
@@ -597,5 +597,5 @@
 		}
 
-		log_msg(LVL_DEBUG, "[] got data - broadcast recv_buffer_cv");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "[] got data - broadcast recv_buffer_cv");
 
 		sock->recv_buffer_used = rcvd;
@@ -622,10 +622,10 @@
 
 	while (true) {
-		log_msg(LVL_DEBUG, "udp_sock_connection: wait");
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: wait");
 		callid = async_get_call(&call);
 		if (!IPC_GET_IMETHOD(call))
 			break;
 
-		log_msg(LVL_DEBUG, "udp_sock_connection: METHOD=%d",
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: METHOD=%d",
 		    (int)IPC_GET_IMETHOD(call));
 
@@ -670,5 +670,5 @@
 
 	/* Clean up */
-	log_msg(LVL_DEBUG, "udp_sock_connection: Clean up");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_sock_connection: Clean up");
 	async_hangup(client.sess);
 	socket_cores_release(NULL, &client.sockets, &gsock, udp_free_sock_data);
Index: uspace/srv/net/udp/ucall.c
===================================================================
--- uspace/srv/net/udp/ucall.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/udp/ucall.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -47,5 +47,5 @@
 	udp_assoc_t *nassoc;
 
-	log_msg(LVL_DEBUG, "udp_uc_create()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_create()");
 	nassoc = udp_assoc_new(NULL, NULL);
 	if (nassoc == NULL)
@@ -59,5 +59,5 @@
 udp_error_t udp_uc_set_foreign(udp_assoc_t *assoc, udp_sock_t *fsock)
 {
-	log_msg(LVL_DEBUG, "udp_uc_set_foreign(%p, %p)", assoc, fsock);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_set_foreign(%p, %p)", assoc, fsock);
 
 	udp_assoc_set_foreign(assoc, fsock);
@@ -67,5 +67,5 @@
 udp_error_t udp_uc_set_local(udp_assoc_t *assoc, udp_sock_t *lsock)
 {
-	log_msg(LVL_DEBUG, "udp_uc_set_local(%p, %p)", assoc, lsock);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_set_local(%p, %p)", assoc, lsock);
 
 	udp_assoc_set_local(assoc, lsock);
@@ -79,5 +79,5 @@
 	udp_msg_t msg;
 
-	log_msg(LVL_DEBUG, "%s: udp_uc_send()", assoc->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_uc_send()", assoc->name);
 
 	msg.data = data;
@@ -103,5 +103,5 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "%s: udp_uc_receive()", assoc->name);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: udp_uc_receive()", assoc->name);
 	rc = udp_assoc_recv(assoc, &msg, fsock);
 	switch (rc) {
@@ -118,5 +118,5 @@
 void udp_uc_status(udp_assoc_t *assoc, udp_assoc_status_t *astatus)
 {
-	log_msg(LVL_DEBUG, "udp_uc_status()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_status()");
 //	cstatus->cstate = conn->cstate;
 }
@@ -124,5 +124,5 @@
 void udp_uc_destroy(udp_assoc_t *assoc)
 {
-	log_msg(LVL_DEBUG, "udp_uc_destroy()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_uc_destroy()");
 	udp_assoc_remove(assoc);
 	udp_assoc_delete(assoc);
Index: uspace/srv/net/udp/udp.c
===================================================================
--- uspace/srv/net/udp/udp.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/udp/udp.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -50,9 +50,9 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "udp_init()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_init()");
 
 	rc = udp_inet_init();
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed connecting to internet service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
 		return ENOENT;
 	}
@@ -60,5 +60,5 @@
 	rc = udp_sock_init();
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed initializing socket service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed initializing socket service.");
 		return ENOENT;
 	}
@@ -73,5 +73,5 @@
 	printf(NAME ": UDP (User Datagram Protocol) service\n");
 
-	rc = log_init(NAME, LVL_DEBUG);
+	rc = log_init(NAME);
 	if (rc != EOK) {
 		printf(NAME ": Failed to initialize log.\n");
Index: uspace/srv/net/udp/udp_inet.c
===================================================================
--- uspace/srv/net/udp/udp_inet.c	(revision 8930624cad0624f7f999680a16864740e48e6484)
+++ uspace/srv/net/udp/udp_inet.c	(revision fedac2f6d42998b2d418219bfe3a62d4d5bc6162)
@@ -61,5 +61,5 @@
 	udp_pdu_t *pdu;
 
-	log_msg(LVL_DEBUG, "udp_inet_ev_recv()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_inet_ev_recv()");
 
 	pdu = udp_pdu_new();
@@ -69,5 +69,5 @@
 	pdu->src.ipv4 = dgram->src.ipv4;
 	pdu->dest.ipv4 = dgram->dest.ipv4;
-	log_msg(LVL_DEBUG, "src: 0x%08x, dest: 0x%08x",
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "src: 0x%08x, dest: 0x%08x",
 	    pdu->src.ipv4, pdu->dest.ipv4);
 
@@ -84,5 +84,5 @@
 	inet_dgram_t dgram;
 
-	log_msg(LVL_DEBUG, "udp_transmit_pdu()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_transmit_pdu()");
 
 	dgram.src.ipv4 = pdu->src.ipv4;
@@ -94,5 +94,5 @@
 	rc = inet_send(&dgram, INET_TTL_MAX, 0);
 	if (rc != EOK)
-		log_msg(LVL_ERROR, "Failed to transmit PDU.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
 
 	return rc;
@@ -105,8 +105,8 @@
 	udp_sockpair_t rident;
 
-	log_msg(LVL_DEBUG, "udp_received_pdu()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_received_pdu()");
 
 	if (udp_pdu_decode(pdu, &rident, &dmsg) != EOK) {
-		log_msg(LVL_WARN, "Not enough memory. PDU dropped.");
+		log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
 		return;
 	}
@@ -124,9 +124,9 @@
 	int rc;
 
-	log_msg(LVL_DEBUG, "udp_inet_init()");
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_inet_init()");
 
 	rc = inet_init(IP_PROTO_UDP, &udp_inet_ev_ops);
 	if (rc != EOK) {
-		log_msg(LVL_ERROR, "Failed connecting to internet service.");
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
 		return ENOENT;
 	}
